17ec681f3Smrg/* 27ec681f3Smrg * Copyright © 2019 Red Hat. 37ec681f3Smrg * 47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 57ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 67ec681f3Smrg * to deal in the Software without restriction, including without limitation 77ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 87ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the 97ec681f3Smrg * Software is furnished to do so, subject to the following conditions: 107ec681f3Smrg * 117ec681f3Smrg * The above copyright notice and this permission notice (including the next 127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 137ec681f3Smrg * Software. 147ec681f3Smrg * 157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 187ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 197ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 207ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 217ec681f3Smrg * IN THE SOFTWARE. 227ec681f3Smrg */ 237ec681f3Smrg 247ec681f3Smrg/* use a gallium context to execute a command buffer */ 257ec681f3Smrg 267ec681f3Smrg#include "lvp_private.h" 277ec681f3Smrg 287ec681f3Smrg#include "pipe/p_context.h" 297ec681f3Smrg#include "pipe/p_state.h" 307ec681f3Smrg#include "lvp_conv.h" 317ec681f3Smrg 327ec681f3Smrg#include "pipe/p_shader_tokens.h" 337ec681f3Smrg#include "tgsi/tgsi_text.h" 347ec681f3Smrg#include "tgsi/tgsi_parse.h" 357ec681f3Smrg 367ec681f3Smrg#include "util/format/u_format.h" 377ec681f3Smrg#include "util/u_surface.h" 387ec681f3Smrg#include "util/u_sampler.h" 397ec681f3Smrg#include "util/u_box.h" 407ec681f3Smrg#include "util/u_inlines.h" 417ec681f3Smrg#include "util/u_prim.h" 427ec681f3Smrg#include "util/u_prim_restart.h" 437ec681f3Smrg#include "util/format/u_format_zs.h" 447ec681f3Smrg 457ec681f3Smrg#include "vk_util.h" 467ec681f3Smrg 477ec681f3Smrg#define VK_PROTOTYPES 487ec681f3Smrg#include <vulkan/vulkan.h> 497ec681f3Smrg 507ec681f3Smrg#define DOUBLE_EQ(a, b) (fabs((a) - (b)) < DBL_EPSILON) 517ec681f3Smrg 527ec681f3Smrgenum gs_output { 537ec681f3Smrg GS_OUTPUT_NONE, 547ec681f3Smrg GS_OUTPUT_NOT_LINES, 557ec681f3Smrg GS_OUTPUT_LINES, 567ec681f3Smrg}; 577ec681f3Smrg 587ec681f3Smrgstruct rendering_state { 597ec681f3Smrg struct pipe_context *pctx; 607ec681f3Smrg struct cso_context *cso; 617ec681f3Smrg 627ec681f3Smrg bool blend_dirty; 637ec681f3Smrg bool rs_dirty; 647ec681f3Smrg bool dsa_dirty; 657ec681f3Smrg bool stencil_ref_dirty; 667ec681f3Smrg bool clip_state_dirty; 677ec681f3Smrg bool blend_color_dirty; 687ec681f3Smrg bool ve_dirty; 697ec681f3Smrg bool vb_dirty; 707ec681f3Smrg bool constbuf_dirty[PIPE_SHADER_TYPES]; 717ec681f3Smrg bool pcbuf_dirty[PIPE_SHADER_TYPES]; 727ec681f3Smrg bool vp_dirty; 737ec681f3Smrg bool scissor_dirty; 747ec681f3Smrg bool ib_dirty; 757ec681f3Smrg bool sample_mask_dirty; 767ec681f3Smrg bool min_samples_dirty; 777ec681f3Smrg struct pipe_draw_indirect_info indirect_info; 787ec681f3Smrg struct pipe_draw_info info; 797ec681f3Smrg 807ec681f3Smrg struct pipe_grid_info dispatch_info; 817ec681f3Smrg struct pipe_framebuffer_state framebuffer; 827ec681f3Smrg 837ec681f3Smrg struct pipe_blend_state blend_state; 847ec681f3Smrg struct { 857ec681f3Smrg float offset_units; 867ec681f3Smrg float offset_scale; 877ec681f3Smrg float offset_clamp; 887ec681f3Smrg bool enabled; 897ec681f3Smrg } depth_bias; 907ec681f3Smrg struct pipe_rasterizer_state rs_state; 917ec681f3Smrg struct pipe_depth_stencil_alpha_state dsa_state; 927ec681f3Smrg 937ec681f3Smrg struct pipe_blend_color blend_color; 947ec681f3Smrg struct pipe_stencil_ref stencil_ref; 957ec681f3Smrg struct pipe_clip_state clip_state; 967ec681f3Smrg 977ec681f3Smrg int num_scissors; 987ec681f3Smrg struct pipe_scissor_state scissors[16]; 997ec681f3Smrg 1007ec681f3Smrg int num_viewports; 1017ec681f3Smrg struct pipe_viewport_state viewports[16]; 1027ec681f3Smrg 1037ec681f3Smrg uint8_t patch_vertices; 1047ec681f3Smrg ubyte index_size; 1057ec681f3Smrg unsigned index_offset; 1067ec681f3Smrg struct pipe_resource *index_buffer; 1077ec681f3Smrg struct pipe_constant_buffer pc_buffer[PIPE_SHADER_TYPES]; 1087ec681f3Smrg struct pipe_constant_buffer const_buffer[PIPE_SHADER_TYPES][16]; 1097ec681f3Smrg int num_const_bufs[PIPE_SHADER_TYPES]; 1107ec681f3Smrg int num_vb; 1117ec681f3Smrg unsigned start_vb; 1127ec681f3Smrg struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS]; 1137ec681f3Smrg struct cso_velems_state velem; 1147ec681f3Smrg 1157ec681f3Smrg struct pipe_sampler_view *sv[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; 1167ec681f3Smrg int num_sampler_views[PIPE_SHADER_TYPES]; 1177ec681f3Smrg struct pipe_sampler_state ss[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; 1187ec681f3Smrg /* cso_context api is stupid */ 1197ec681f3Smrg const struct pipe_sampler_state *cso_ss_ptr[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; 1207ec681f3Smrg int num_sampler_states[PIPE_SHADER_TYPES]; 1217ec681f3Smrg bool sv_dirty[PIPE_SHADER_TYPES]; 1227ec681f3Smrg bool ss_dirty[PIPE_SHADER_TYPES]; 1237ec681f3Smrg 1247ec681f3Smrg struct pipe_image_view iv[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES]; 1257ec681f3Smrg int num_shader_images[PIPE_SHADER_TYPES]; 1267ec681f3Smrg struct pipe_shader_buffer sb[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS]; 1277ec681f3Smrg int num_shader_buffers[PIPE_SHADER_TYPES]; 1287ec681f3Smrg bool iv_dirty[PIPE_SHADER_TYPES]; 1297ec681f3Smrg bool sb_dirty[PIPE_SHADER_TYPES]; 1307ec681f3Smrg bool disable_multisample; 1317ec681f3Smrg enum gs_output gs_output_lines : 2; 1327ec681f3Smrg 1337ec681f3Smrg uint32_t color_write_disables:8; 1347ec681f3Smrg bool has_color_write_disables:1; 1357ec681f3Smrg uint32_t pad:13; 1367ec681f3Smrg 1377ec681f3Smrg void *ss_cso[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; 1387ec681f3Smrg void *velems_cso; 1397ec681f3Smrg 1407ec681f3Smrg uint8_t push_constants[128 * 4]; 1417ec681f3Smrg 1427ec681f3Smrg const struct lvp_render_pass *pass; 1437ec681f3Smrg uint32_t subpass; 1447ec681f3Smrg const struct lvp_framebuffer *vk_framebuffer; 1457ec681f3Smrg VkRect2D render_area; 1467ec681f3Smrg 1477ec681f3Smrg uint32_t sample_mask; 1487ec681f3Smrg unsigned min_samples; 1497ec681f3Smrg 1507ec681f3Smrg struct lvp_image_view **imageless_views; 1517ec681f3Smrg struct lvp_attachment_state *attachments; 1527ec681f3Smrg VkImageAspectFlags *pending_clear_aspects; 1537ec681f3Smrg uint32_t *cleared_views; 1547ec681f3Smrg int num_pending_aspects; 1557ec681f3Smrg 1567ec681f3Smrg uint32_t num_so_targets; 1577ec681f3Smrg struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS]; 1587ec681f3Smrg uint32_t so_offsets[PIPE_MAX_SO_BUFFERS]; 1597ec681f3Smrg}; 1607ec681f3Smrg 1617ec681f3SmrgALWAYS_INLINE static void 1627ec681f3Smrgassert_subresource_layers(const struct pipe_resource *pres, const VkImageSubresourceLayers *layers, const VkOffset3D *offsets) 1637ec681f3Smrg{ 1647ec681f3Smrg#ifndef NDEBUG 1657ec681f3Smrg if (pres->target == PIPE_TEXTURE_3D) { 1667ec681f3Smrg assert(layers->baseArrayLayer == 0); 1677ec681f3Smrg assert(layers->layerCount == 1); 1687ec681f3Smrg assert(offsets[0].z <= pres->depth0); 1697ec681f3Smrg assert(offsets[1].z <= pres->depth0); 1707ec681f3Smrg } else { 1717ec681f3Smrg assert(layers->baseArrayLayer < pres->array_size); 1727ec681f3Smrg assert(layers->baseArrayLayer + layers->layerCount <= pres->array_size); 1737ec681f3Smrg assert(offsets[0].z == 0); 1747ec681f3Smrg assert(offsets[1].z == 1); 1757ec681f3Smrg } 1767ec681f3Smrg#endif 1777ec681f3Smrg} 1787ec681f3Smrg 1797ec681f3Smrgstatic void emit_compute_state(struct rendering_state *state) 1807ec681f3Smrg{ 1817ec681f3Smrg if (state->iv_dirty[PIPE_SHADER_COMPUTE]) { 1827ec681f3Smrg state->pctx->set_shader_images(state->pctx, PIPE_SHADER_COMPUTE, 1837ec681f3Smrg 0, state->num_shader_images[PIPE_SHADER_COMPUTE], 1847ec681f3Smrg 0, state->iv[PIPE_SHADER_COMPUTE]); 1857ec681f3Smrg state->iv_dirty[PIPE_SHADER_COMPUTE] = false; 1867ec681f3Smrg } 1877ec681f3Smrg 1887ec681f3Smrg if (state->pcbuf_dirty[PIPE_SHADER_COMPUTE]) { 1897ec681f3Smrg state->pctx->set_constant_buffer(state->pctx, PIPE_SHADER_COMPUTE, 1907ec681f3Smrg 0, false, &state->pc_buffer[PIPE_SHADER_COMPUTE]); 1917ec681f3Smrg state->pcbuf_dirty[PIPE_SHADER_COMPUTE] = false; 1927ec681f3Smrg } 1937ec681f3Smrg 1947ec681f3Smrg if (state->constbuf_dirty[PIPE_SHADER_COMPUTE]) { 1957ec681f3Smrg for (unsigned i = 0; i < state->num_const_bufs[PIPE_SHADER_COMPUTE]; i++) 1967ec681f3Smrg state->pctx->set_constant_buffer(state->pctx, PIPE_SHADER_COMPUTE, 1977ec681f3Smrg i + 1, false, &state->const_buffer[PIPE_SHADER_COMPUTE][i]); 1987ec681f3Smrg state->constbuf_dirty[PIPE_SHADER_COMPUTE] = false; 1997ec681f3Smrg } 2007ec681f3Smrg 2017ec681f3Smrg if (state->sb_dirty[PIPE_SHADER_COMPUTE]) { 2027ec681f3Smrg state->pctx->set_shader_buffers(state->pctx, PIPE_SHADER_COMPUTE, 2037ec681f3Smrg 0, state->num_shader_buffers[PIPE_SHADER_COMPUTE], 2047ec681f3Smrg state->sb[PIPE_SHADER_COMPUTE], 0); 2057ec681f3Smrg state->sb_dirty[PIPE_SHADER_COMPUTE] = false; 2067ec681f3Smrg } 2077ec681f3Smrg 2087ec681f3Smrg if (state->sv_dirty[PIPE_SHADER_COMPUTE]) { 2097ec681f3Smrg state->pctx->set_sampler_views(state->pctx, PIPE_SHADER_COMPUTE, 0, state->num_sampler_views[PIPE_SHADER_COMPUTE], 2107ec681f3Smrg 0, false, state->sv[PIPE_SHADER_COMPUTE]); 2117ec681f3Smrg state->sv_dirty[PIPE_SHADER_COMPUTE] = false; 2127ec681f3Smrg } 2137ec681f3Smrg 2147ec681f3Smrg if (state->ss_dirty[PIPE_SHADER_COMPUTE]) { 2157ec681f3Smrg for (unsigned i = 0; i < state->num_sampler_states[PIPE_SHADER_COMPUTE]; i++) { 2167ec681f3Smrg if (state->ss_cso[PIPE_SHADER_COMPUTE][i]) 2177ec681f3Smrg state->pctx->delete_sampler_state(state->pctx, state->ss_cso[PIPE_SHADER_COMPUTE][i]); 2187ec681f3Smrg state->ss_cso[PIPE_SHADER_COMPUTE][i] = state->pctx->create_sampler_state(state->pctx, &state->ss[PIPE_SHADER_COMPUTE][i]); 2197ec681f3Smrg } 2207ec681f3Smrg state->pctx->bind_sampler_states(state->pctx, PIPE_SHADER_COMPUTE, 0, state->num_sampler_states[PIPE_SHADER_COMPUTE], state->ss_cso[PIPE_SHADER_COMPUTE]); 2217ec681f3Smrg state->ss_dirty[PIPE_SHADER_COMPUTE] = false; 2227ec681f3Smrg } 2237ec681f3Smrg} 2247ec681f3Smrg 2257ec681f3Smrgstatic void emit_state(struct rendering_state *state) 2267ec681f3Smrg{ 2277ec681f3Smrg int sh; 2287ec681f3Smrg if (state->blend_dirty) { 2297ec681f3Smrg uint32_t mask = 0; 2307ec681f3Smrg /* zero out the colormask values for disabled attachments */ 2317ec681f3Smrg if (state->has_color_write_disables && state->color_write_disables) { 2327ec681f3Smrg u_foreach_bit(att, state->color_write_disables) { 2337ec681f3Smrg mask |= state->blend_state.rt[att].colormask << (att * 4); 2347ec681f3Smrg state->blend_state.rt[att].colormask = 0; 2357ec681f3Smrg } 2367ec681f3Smrg } 2377ec681f3Smrg cso_set_blend(state->cso, &state->blend_state); 2387ec681f3Smrg /* reset colormasks using saved bitmask */ 2397ec681f3Smrg if (state->has_color_write_disables && state->color_write_disables) { 2407ec681f3Smrg const uint32_t att_mask = BITFIELD_MASK(4); 2417ec681f3Smrg u_foreach_bit(att, state->color_write_disables) { 2427ec681f3Smrg state->blend_state.rt[att].colormask = (mask >> (att * 4)) & att_mask; 2437ec681f3Smrg } 2447ec681f3Smrg } 2457ec681f3Smrg state->blend_dirty = false; 2467ec681f3Smrg } 2477ec681f3Smrg 2487ec681f3Smrg if (state->rs_dirty) { 2497ec681f3Smrg bool ms = state->rs_state.multisample; 2507ec681f3Smrg if (state->disable_multisample && 2517ec681f3Smrg (state->gs_output_lines == GS_OUTPUT_LINES || 2527ec681f3Smrg (state->gs_output_lines == GS_OUTPUT_NONE && u_reduced_prim(state->info.mode) == PIPE_PRIM_LINES))) 2537ec681f3Smrg state->rs_state.multisample = false; 2547ec681f3Smrg assert(offsetof(struct pipe_rasterizer_state, offset_clamp) - offsetof(struct pipe_rasterizer_state, offset_units) == sizeof(float) * 2); 2557ec681f3Smrg if (state->depth_bias.enabled) { 2567ec681f3Smrg memcpy(&state->rs_state.offset_units, &state->depth_bias, sizeof(float) * 3); 2577ec681f3Smrg } else { 2587ec681f3Smrg memset(&state->rs_state.offset_units, 0, sizeof(float) * 3); 2597ec681f3Smrg } 2607ec681f3Smrg cso_set_rasterizer(state->cso, &state->rs_state); 2617ec681f3Smrg state->rs_dirty = false; 2627ec681f3Smrg state->rs_state.multisample = ms; 2637ec681f3Smrg } 2647ec681f3Smrg 2657ec681f3Smrg if (state->dsa_dirty) { 2667ec681f3Smrg cso_set_depth_stencil_alpha(state->cso, &state->dsa_state); 2677ec681f3Smrg state->dsa_dirty = false; 2687ec681f3Smrg } 2697ec681f3Smrg 2707ec681f3Smrg if (state->sample_mask_dirty) { 2717ec681f3Smrg cso_set_sample_mask(state->cso, state->sample_mask); 2727ec681f3Smrg state->sample_mask_dirty = false; 2737ec681f3Smrg } 2747ec681f3Smrg 2757ec681f3Smrg if (state->min_samples_dirty) { 2767ec681f3Smrg cso_set_min_samples(state->cso, state->min_samples); 2777ec681f3Smrg state->min_samples_dirty = false; 2787ec681f3Smrg } 2797ec681f3Smrg 2807ec681f3Smrg if (state->blend_color_dirty) { 2817ec681f3Smrg state->pctx->set_blend_color(state->pctx, &state->blend_color); 2827ec681f3Smrg state->blend_color_dirty = false; 2837ec681f3Smrg } 2847ec681f3Smrg 2857ec681f3Smrg if (state->stencil_ref_dirty) { 2867ec681f3Smrg cso_set_stencil_ref(state->cso, state->stencil_ref); 2877ec681f3Smrg state->stencil_ref_dirty = false; 2887ec681f3Smrg } 2897ec681f3Smrg 2907ec681f3Smrg if (state->vb_dirty) { 2917ec681f3Smrg cso_set_vertex_buffers(state->cso, state->start_vb, state->num_vb, state->vb); 2927ec681f3Smrg state->vb_dirty = false; 2937ec681f3Smrg } 2947ec681f3Smrg 2957ec681f3Smrg if (state->ve_dirty) { 2967ec681f3Smrg cso_set_vertex_elements(state->cso, &state->velem); 2977ec681f3Smrg state->ve_dirty = false; 2987ec681f3Smrg } 2997ec681f3Smrg 3007ec681f3Smrg 3017ec681f3Smrg for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { 3027ec681f3Smrg if (state->constbuf_dirty[sh]) { 3037ec681f3Smrg for (unsigned idx = 0; idx < state->num_const_bufs[sh]; idx++) 3047ec681f3Smrg state->pctx->set_constant_buffer(state->pctx, sh, 3057ec681f3Smrg idx + 1, false, &state->const_buffer[sh][idx]); 3067ec681f3Smrg } 3077ec681f3Smrg state->constbuf_dirty[sh] = false; 3087ec681f3Smrg } 3097ec681f3Smrg 3107ec681f3Smrg for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { 3117ec681f3Smrg if (state->pcbuf_dirty[sh]) { 3127ec681f3Smrg state->pctx->set_constant_buffer(state->pctx, sh, 3137ec681f3Smrg 0, false, &state->pc_buffer[sh]); 3147ec681f3Smrg } 3157ec681f3Smrg } 3167ec681f3Smrg 3177ec681f3Smrg for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { 3187ec681f3Smrg if (state->sb_dirty[sh]) { 3197ec681f3Smrg state->pctx->set_shader_buffers(state->pctx, sh, 3207ec681f3Smrg 0, state->num_shader_buffers[sh], 3217ec681f3Smrg state->sb[sh], 0); 3227ec681f3Smrg } 3237ec681f3Smrg } 3247ec681f3Smrg 3257ec681f3Smrg for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { 3267ec681f3Smrg if (state->iv_dirty[sh]) { 3277ec681f3Smrg state->pctx->set_shader_images(state->pctx, sh, 3287ec681f3Smrg 0, state->num_shader_images[sh], 0, 3297ec681f3Smrg state->iv[sh]); 3307ec681f3Smrg } 3317ec681f3Smrg } 3327ec681f3Smrg 3337ec681f3Smrg for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { 3347ec681f3Smrg 3357ec681f3Smrg if (!state->sv_dirty[sh]) 3367ec681f3Smrg continue; 3377ec681f3Smrg 3387ec681f3Smrg state->pctx->set_sampler_views(state->pctx, sh, 0, state->num_sampler_views[sh], 3397ec681f3Smrg 0, false, state->sv[sh]); 3407ec681f3Smrg state->sv_dirty[sh] = false; 3417ec681f3Smrg } 3427ec681f3Smrg 3437ec681f3Smrg for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { 3447ec681f3Smrg if (!state->ss_dirty[sh]) 3457ec681f3Smrg continue; 3467ec681f3Smrg 3477ec681f3Smrg cso_set_samplers(state->cso, sh, state->num_sampler_states[sh], state->cso_ss_ptr[sh]); 3487ec681f3Smrg } 3497ec681f3Smrg 3507ec681f3Smrg if (state->vp_dirty) { 3517ec681f3Smrg state->pctx->set_viewport_states(state->pctx, 0, state->num_viewports, state->viewports); 3527ec681f3Smrg state->vp_dirty = false; 3537ec681f3Smrg } 3547ec681f3Smrg 3557ec681f3Smrg if (state->scissor_dirty) { 3567ec681f3Smrg state->pctx->set_scissor_states(state->pctx, 0, state->num_scissors, state->scissors); 3577ec681f3Smrg state->scissor_dirty = false; 3587ec681f3Smrg } 3597ec681f3Smrg} 3607ec681f3Smrg 3617ec681f3Smrgstatic void handle_compute_pipeline(struct vk_cmd_queue_entry *cmd, 3627ec681f3Smrg struct rendering_state *state) 3637ec681f3Smrg{ 3647ec681f3Smrg LVP_FROM_HANDLE(lvp_pipeline, pipeline, cmd->u.bind_pipeline.pipeline); 3657ec681f3Smrg 3667ec681f3Smrg state->dispatch_info.block[0] = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.workgroup_size[0]; 3677ec681f3Smrg state->dispatch_info.block[1] = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.workgroup_size[1]; 3687ec681f3Smrg state->dispatch_info.block[2] = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.workgroup_size[2]; 3697ec681f3Smrg state->pctx->bind_compute_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_COMPUTE]); 3707ec681f3Smrg} 3717ec681f3Smrg 3727ec681f3Smrgstatic void 3737ec681f3Smrgget_viewport_xform(const VkViewport *viewport, 3747ec681f3Smrg float scale[3], float translate[3]) 3757ec681f3Smrg{ 3767ec681f3Smrg float x = viewport->x; 3777ec681f3Smrg float y = viewport->y; 3787ec681f3Smrg float half_width = 0.5f * viewport->width; 3797ec681f3Smrg float half_height = 0.5f * viewport->height; 3807ec681f3Smrg double n = viewport->minDepth; 3817ec681f3Smrg double f = viewport->maxDepth; 3827ec681f3Smrg 3837ec681f3Smrg scale[0] = half_width; 3847ec681f3Smrg translate[0] = half_width + x; 3857ec681f3Smrg scale[1] = half_height; 3867ec681f3Smrg translate[1] = half_height + y; 3877ec681f3Smrg 3887ec681f3Smrg scale[2] = (f - n); 3897ec681f3Smrg translate[2] = n; 3907ec681f3Smrg} 3917ec681f3Smrg 3927ec681f3Smrg/* enum re-indexing: 3937ec681f3Smrg 3947ec681f3Smrg VK_DYNAMIC_STATE_VIEWPORT 3957ec681f3Smrg VK_DYNAMIC_STATE_SCISSOR 3967ec681f3Smrg VK_DYNAMIC_STATE_LINE_WIDTH 3977ec681f3Smrg VK_DYNAMIC_STATE_DEPTH_BIAS 3987ec681f3Smrg VK_DYNAMIC_STATE_BLEND_CONSTANTS 3997ec681f3Smrg VK_DYNAMIC_STATE_DEPTH_BOUNDS 4007ec681f3Smrg VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK 4017ec681f3Smrg VK_DYNAMIC_STATE_STENCIL_WRITE_MASK 4027ec681f3Smrg VK_DYNAMIC_STATE_STENCIL_REFERENCE 4037ec681f3Smrg 4047ec681f3Smrg VK_DYNAMIC_STATE_LINE_STIPPLE_EXT 4057ec681f3Smrg 4067ec681f3Smrg VK_DYNAMIC_STATE_CULL_MODE_EXT 4077ec681f3Smrg VK_DYNAMIC_STATE_FRONT_FACE_EXT 4087ec681f3Smrg VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT 4097ec681f3Smrg VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT 4107ec681f3Smrg VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT 4117ec681f3Smrg VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT 4127ec681f3Smrg VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT 4137ec681f3Smrg VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT 4147ec681f3Smrg VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT 4157ec681f3Smrg VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT 4167ec681f3Smrg VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT 4177ec681f3Smrg VK_DYNAMIC_STATE_STENCIL_OP_EXT 4187ec681f3Smrg 4197ec681f3Smrg VK_DYNAMIC_STATE_VERTEX_INPUT_EXT 4207ec681f3Smrg 4217ec681f3Smrg VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT 4227ec681f3Smrg VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT 4237ec681f3Smrg VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT 4247ec681f3Smrg VK_DYNAMIC_STATE_LOGIC_OP_EXT 4257ec681f3Smrg VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT 4267ec681f3Smrg 4277ec681f3Smrg VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT 4287ec681f3Smrg*/ 4297ec681f3Smrgstatic int conv_dynamic_state_idx(VkDynamicState dyn_state) 4307ec681f3Smrg{ 4317ec681f3Smrg if (dyn_state <= VK_DYNAMIC_STATE_STENCIL_REFERENCE) 4327ec681f3Smrg return dyn_state; 4337ec681f3Smrg if (dyn_state == VK_DYNAMIC_STATE_LINE_STIPPLE_EXT) 4347ec681f3Smrg /* this one has a weird id, map after the normal dynamic state ones */ 4357ec681f3Smrg return VK_DYNAMIC_STATE_STENCIL_REFERENCE + 1; 4367ec681f3Smrg if (dyn_state >= VK_DYNAMIC_STATE_CULL_MODE_EXT && 4377ec681f3Smrg dyn_state <= VK_DYNAMIC_STATE_STENCIL_OP_EXT) 4387ec681f3Smrg return dyn_state - VK_DYNAMIC_STATE_CULL_MODE_EXT + VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2; 4397ec681f3Smrg if (dyn_state == VK_DYNAMIC_STATE_VERTEX_INPUT_EXT) 4407ec681f3Smrg return (VK_DYNAMIC_STATE_STENCIL_OP_EXT - VK_DYNAMIC_STATE_CULL_MODE_EXT) + VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2 + 1; 4417ec681f3Smrg if (dyn_state >= VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT && 4427ec681f3Smrg dyn_state <= VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT) 4437ec681f3Smrg return dyn_state - VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT + 4447ec681f3Smrg VK_DYNAMIC_STATE_STENCIL_OP_EXT - VK_DYNAMIC_STATE_CULL_MODE_EXT + 4457ec681f3Smrg VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2 + 1 + 1; 4467ec681f3Smrg if (dyn_state == VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT) 4477ec681f3Smrg return VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT - VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT + 4487ec681f3Smrg VK_DYNAMIC_STATE_STENCIL_OP_EXT - VK_DYNAMIC_STATE_CULL_MODE_EXT + 4497ec681f3Smrg VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2 + 1 + 1 + 1; 4507ec681f3Smrg assert(0); 4517ec681f3Smrg return -1; 4527ec681f3Smrg} 4537ec681f3Smrg 4547ec681f3Smrgstatic void handle_graphics_pipeline(struct vk_cmd_queue_entry *cmd, 4557ec681f3Smrg struct rendering_state *state) 4567ec681f3Smrg{ 4577ec681f3Smrg LVP_FROM_HANDLE(lvp_pipeline, pipeline, cmd->u.bind_pipeline.pipeline); 4587ec681f3Smrg bool dynamic_states[VK_DYNAMIC_STATE_STENCIL_REFERENCE+32]; 4597ec681f3Smrg unsigned fb_samples = 0; 4607ec681f3Smrg 4617ec681f3Smrg memset(dynamic_states, 0, sizeof(dynamic_states)); 4627ec681f3Smrg if (pipeline->graphics_create_info.pDynamicState) 4637ec681f3Smrg { 4647ec681f3Smrg const VkPipelineDynamicStateCreateInfo *dyn = pipeline->graphics_create_info.pDynamicState; 4657ec681f3Smrg int i; 4667ec681f3Smrg for (i = 0; i < dyn->dynamicStateCount; i++) { 4677ec681f3Smrg int idx = conv_dynamic_state_idx(dyn->pDynamicStates[i]); 4687ec681f3Smrg if (idx == -1) 4697ec681f3Smrg continue; 4707ec681f3Smrg dynamic_states[idx] = true; 4717ec681f3Smrg } 4727ec681f3Smrg } 4737ec681f3Smrg state->has_color_write_disables = dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT)]; 4747ec681f3Smrg 4757ec681f3Smrg bool has_stage[PIPE_SHADER_TYPES] = { false }; 4767ec681f3Smrg 4777ec681f3Smrg state->pctx->bind_gs_state(state->pctx, NULL); 4787ec681f3Smrg if (state->pctx->bind_tcs_state) 4797ec681f3Smrg state->pctx->bind_tcs_state(state->pctx, NULL); 4807ec681f3Smrg if (state->pctx->bind_tes_state) 4817ec681f3Smrg state->pctx->bind_tes_state(state->pctx, NULL); 4827ec681f3Smrg state->gs_output_lines = GS_OUTPUT_NONE; 4837ec681f3Smrg { 4847ec681f3Smrg int i; 4857ec681f3Smrg for (i = 0; i < pipeline->graphics_create_info.stageCount; i++) { 4867ec681f3Smrg const VkPipelineShaderStageCreateInfo *sh = &pipeline->graphics_create_info.pStages[i]; 4877ec681f3Smrg switch (sh->stage) { 4887ec681f3Smrg case VK_SHADER_STAGE_FRAGMENT_BIT: 4897ec681f3Smrg state->pctx->bind_fs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_FRAGMENT]); 4907ec681f3Smrg has_stage[PIPE_SHADER_FRAGMENT] = true; 4917ec681f3Smrg break; 4927ec681f3Smrg case VK_SHADER_STAGE_VERTEX_BIT: 4937ec681f3Smrg state->pctx->bind_vs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_VERTEX]); 4947ec681f3Smrg has_stage[PIPE_SHADER_VERTEX] = true; 4957ec681f3Smrg break; 4967ec681f3Smrg case VK_SHADER_STAGE_GEOMETRY_BIT: 4977ec681f3Smrg state->pctx->bind_gs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_GEOMETRY]); 4987ec681f3Smrg state->gs_output_lines = pipeline->gs_output_lines ? GS_OUTPUT_LINES : GS_OUTPUT_NOT_LINES; 4997ec681f3Smrg has_stage[PIPE_SHADER_GEOMETRY] = true; 5007ec681f3Smrg break; 5017ec681f3Smrg case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: 5027ec681f3Smrg state->pctx->bind_tcs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_TESS_CTRL]); 5037ec681f3Smrg has_stage[PIPE_SHADER_TESS_CTRL] = true; 5047ec681f3Smrg break; 5057ec681f3Smrg case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: 5067ec681f3Smrg state->pctx->bind_tes_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_TESS_EVAL]); 5077ec681f3Smrg has_stage[PIPE_SHADER_TESS_EVAL] = true; 5087ec681f3Smrg break; 5097ec681f3Smrg default: 5107ec681f3Smrg assert(0); 5117ec681f3Smrg break; 5127ec681f3Smrg } 5137ec681f3Smrg } 5147ec681f3Smrg } 5157ec681f3Smrg 5167ec681f3Smrg /* there should always be a dummy fs. */ 5177ec681f3Smrg if (!has_stage[PIPE_SHADER_FRAGMENT]) 5187ec681f3Smrg state->pctx->bind_fs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_FRAGMENT]); 5197ec681f3Smrg if (state->pctx->bind_gs_state && !has_stage[PIPE_SHADER_GEOMETRY]) 5207ec681f3Smrg state->pctx->bind_gs_state(state->pctx, NULL); 5217ec681f3Smrg if (state->pctx->bind_tcs_state && !has_stage[PIPE_SHADER_TESS_CTRL]) 5227ec681f3Smrg state->pctx->bind_tcs_state(state->pctx, NULL); 5237ec681f3Smrg if (state->pctx->bind_tes_state && !has_stage[PIPE_SHADER_TESS_EVAL]) 5247ec681f3Smrg state->pctx->bind_tes_state(state->pctx, NULL); 5257ec681f3Smrg 5267ec681f3Smrg /* rasterization state */ 5277ec681f3Smrg if (pipeline->graphics_create_info.pRasterizationState) { 5287ec681f3Smrg const VkPipelineRasterizationStateCreateInfo *rsc = pipeline->graphics_create_info.pRasterizationState; 5297ec681f3Smrg const VkPipelineRasterizationDepthClipStateCreateInfoEXT *depth_clip_state = 5307ec681f3Smrg vk_find_struct_const(rsc->pNext, PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT); 5317ec681f3Smrg state->rs_state.depth_clamp = rsc->depthClampEnable; 5327ec681f3Smrg if (!depth_clip_state) 5337ec681f3Smrg state->rs_state.depth_clip_near = state->rs_state.depth_clip_far = !rsc->depthClampEnable; 5347ec681f3Smrg else 5357ec681f3Smrg state->rs_state.depth_clip_near = state->rs_state.depth_clip_far = depth_clip_state->depthClipEnable; 5367ec681f3Smrg 5377ec681f3Smrg if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT)]) 5387ec681f3Smrg state->rs_state.rasterizer_discard = rsc->rasterizerDiscardEnable; 5397ec681f3Smrg 5407ec681f3Smrg state->rs_state.line_smooth = pipeline->line_smooth; 5417ec681f3Smrg state->rs_state.line_stipple_enable = pipeline->line_stipple_enable; 5427ec681f3Smrg state->rs_state.fill_front = vk_polygon_mode_to_pipe(rsc->polygonMode); 5437ec681f3Smrg state->rs_state.fill_back = vk_polygon_mode_to_pipe(rsc->polygonMode); 5447ec681f3Smrg state->rs_state.point_size_per_vertex = true; 5457ec681f3Smrg state->rs_state.flatshade_first = !pipeline->provoking_vertex_last; 5467ec681f3Smrg state->rs_state.point_quad_rasterization = true; 5477ec681f3Smrg state->rs_state.clip_halfz = true; 5487ec681f3Smrg state->rs_state.half_pixel_center = true; 5497ec681f3Smrg state->rs_state.scissor = true; 5507ec681f3Smrg state->rs_state.no_ms_sample_mask_out = true; 5517ec681f3Smrg state->rs_state.line_rectangular = pipeline->line_rectangular; 5527ec681f3Smrg 5537ec681f3Smrg if (!dynamic_states[VK_DYNAMIC_STATE_LINE_WIDTH]) 5547ec681f3Smrg state->rs_state.line_width = rsc->lineWidth; 5557ec681f3Smrg if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_LINE_STIPPLE_EXT)]) { 5567ec681f3Smrg state->rs_state.line_stipple_factor = pipeline->line_stipple_factor; 5577ec681f3Smrg state->rs_state.line_stipple_pattern = pipeline->line_stipple_pattern; 5587ec681f3Smrg } 5597ec681f3Smrg 5607ec681f3Smrg if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT)]) 5617ec681f3Smrg state->depth_bias.enabled = pipeline->graphics_create_info.pRasterizationState->depthBiasEnable; 5627ec681f3Smrg if (!dynamic_states[VK_DYNAMIC_STATE_DEPTH_BIAS]) { 5637ec681f3Smrg state->depth_bias.offset_units = rsc->depthBiasConstantFactor; 5647ec681f3Smrg state->depth_bias.offset_scale = rsc->depthBiasSlopeFactor; 5657ec681f3Smrg state->depth_bias.offset_clamp = rsc->depthBiasClamp; 5667ec681f3Smrg } 5677ec681f3Smrg 5687ec681f3Smrg if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_CULL_MODE_EXT)]) 5697ec681f3Smrg state->rs_state.cull_face = vk_cull_to_pipe(rsc->cullMode); 5707ec681f3Smrg 5717ec681f3Smrg if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_FRONT_FACE_EXT)]) 5727ec681f3Smrg state->rs_state.front_ccw = (rsc->frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE); 5737ec681f3Smrg state->rs_dirty = true; 5747ec681f3Smrg } 5757ec681f3Smrg 5767ec681f3Smrg state->disable_multisample = pipeline->disable_multisample; 5777ec681f3Smrg if (pipeline->graphics_create_info.pMultisampleState) { 5787ec681f3Smrg const VkPipelineMultisampleStateCreateInfo *ms = pipeline->graphics_create_info.pMultisampleState; 5797ec681f3Smrg state->rs_state.multisample = ms->rasterizationSamples > 1; 5807ec681f3Smrg state->sample_mask = ms->pSampleMask ? ms->pSampleMask[0] : 0xffffffff; 5817ec681f3Smrg state->blend_state.alpha_to_coverage = ms->alphaToCoverageEnable; 5827ec681f3Smrg state->blend_state.alpha_to_one = ms->alphaToOneEnable; 5837ec681f3Smrg state->blend_dirty = true; 5847ec681f3Smrg state->rs_dirty = true; 5857ec681f3Smrg state->min_samples = 1; 5867ec681f3Smrg state->sample_mask_dirty = true; 5877ec681f3Smrg fb_samples = ms->rasterizationSamples; 5887ec681f3Smrg if (ms->sampleShadingEnable) { 5897ec681f3Smrg state->min_samples = ceil(ms->rasterizationSamples * ms->minSampleShading); 5907ec681f3Smrg if (state->min_samples > 1) 5917ec681f3Smrg state->min_samples = ms->rasterizationSamples; 5927ec681f3Smrg if (state->min_samples < 1) 5937ec681f3Smrg state->min_samples = 1; 5947ec681f3Smrg } 5957ec681f3Smrg if (pipeline->force_min_sample) 5967ec681f3Smrg state->min_samples = ms->rasterizationSamples; 5977ec681f3Smrg state->min_samples_dirty = true; 5987ec681f3Smrg } else { 5997ec681f3Smrg state->rs_state.multisample = false; 6007ec681f3Smrg state->sample_mask_dirty = state->sample_mask != 0xffffffff; 6017ec681f3Smrg state->sample_mask = 0xffffffff; 6027ec681f3Smrg state->min_samples_dirty = state->min_samples; 6037ec681f3Smrg state->min_samples = 0; 6047ec681f3Smrg state->blend_dirty |= state->blend_state.alpha_to_coverage || state->blend_state.alpha_to_one; 6057ec681f3Smrg state->blend_state.alpha_to_coverage = false; 6067ec681f3Smrg state->blend_state.alpha_to_one = false; 6077ec681f3Smrg state->rs_dirty = true; 6087ec681f3Smrg } 6097ec681f3Smrg 6107ec681f3Smrg if (pipeline->graphics_create_info.pDepthStencilState) { 6117ec681f3Smrg const VkPipelineDepthStencilStateCreateInfo *dsa = pipeline->graphics_create_info.pDepthStencilState; 6127ec681f3Smrg 6137ec681f3Smrg if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT)]) 6147ec681f3Smrg state->dsa_state.depth_enabled = dsa->depthTestEnable; 6157ec681f3Smrg if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT)]) 6167ec681f3Smrg state->dsa_state.depth_writemask = dsa->depthWriteEnable; 6177ec681f3Smrg if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT)]) 6187ec681f3Smrg state->dsa_state.depth_func = dsa->depthCompareOp; 6197ec681f3Smrg if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT)]) 6207ec681f3Smrg state->dsa_state.depth_bounds_test = dsa->depthBoundsTestEnable; 6217ec681f3Smrg 6227ec681f3Smrg if (!dynamic_states[VK_DYNAMIC_STATE_DEPTH_BOUNDS]) { 6237ec681f3Smrg state->dsa_state.depth_bounds_min = dsa->minDepthBounds; 6247ec681f3Smrg state->dsa_state.depth_bounds_max = dsa->maxDepthBounds; 6257ec681f3Smrg } 6267ec681f3Smrg 6277ec681f3Smrg if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT)]) { 6287ec681f3Smrg state->dsa_state.stencil[0].enabled = dsa->stencilTestEnable; 6297ec681f3Smrg state->dsa_state.stencil[1].enabled = dsa->stencilTestEnable; 6307ec681f3Smrg } 6317ec681f3Smrg 6327ec681f3Smrg if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_STENCIL_OP_EXT)]) { 6337ec681f3Smrg state->dsa_state.stencil[0].func = dsa->front.compareOp; 6347ec681f3Smrg state->dsa_state.stencil[0].fail_op = vk_conv_stencil_op(dsa->front.failOp); 6357ec681f3Smrg state->dsa_state.stencil[0].zpass_op = vk_conv_stencil_op(dsa->front.passOp); 6367ec681f3Smrg state->dsa_state.stencil[0].zfail_op = vk_conv_stencil_op(dsa->front.depthFailOp); 6377ec681f3Smrg 6387ec681f3Smrg state->dsa_state.stencil[1].func = dsa->back.compareOp; 6397ec681f3Smrg state->dsa_state.stencil[1].fail_op = vk_conv_stencil_op(dsa->back.failOp); 6407ec681f3Smrg state->dsa_state.stencil[1].zpass_op = vk_conv_stencil_op(dsa->back.passOp); 6417ec681f3Smrg state->dsa_state.stencil[1].zfail_op = vk_conv_stencil_op(dsa->back.depthFailOp); 6427ec681f3Smrg } 6437ec681f3Smrg 6447ec681f3Smrg if (!dynamic_states[VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK]) { 6457ec681f3Smrg state->dsa_state.stencil[0].valuemask = dsa->front.compareMask; 6467ec681f3Smrg state->dsa_state.stencil[1].valuemask = dsa->back.compareMask; 6477ec681f3Smrg } 6487ec681f3Smrg 6497ec681f3Smrg if (!dynamic_states[VK_DYNAMIC_STATE_STENCIL_WRITE_MASK]) { 6507ec681f3Smrg state->dsa_state.stencil[0].writemask = dsa->front.writeMask; 6517ec681f3Smrg state->dsa_state.stencil[1].writemask = dsa->back.writeMask; 6527ec681f3Smrg } 6537ec681f3Smrg 6547ec681f3Smrg if (dsa->stencilTestEnable) { 6557ec681f3Smrg if (!dynamic_states[VK_DYNAMIC_STATE_STENCIL_REFERENCE]) { 6567ec681f3Smrg state->stencil_ref.ref_value[0] = dsa->front.reference; 6577ec681f3Smrg state->stencil_ref.ref_value[1] = dsa->back.reference; 6587ec681f3Smrg state->stencil_ref_dirty = true; 6597ec681f3Smrg } 6607ec681f3Smrg } 6617ec681f3Smrg } else 6627ec681f3Smrg memset(&state->dsa_state, 0, sizeof(state->dsa_state)); 6637ec681f3Smrg state->dsa_dirty = true; 6647ec681f3Smrg 6657ec681f3Smrg if (pipeline->graphics_create_info.pColorBlendState) { 6667ec681f3Smrg const VkPipelineColorBlendStateCreateInfo *cb = pipeline->graphics_create_info.pColorBlendState; 6677ec681f3Smrg int i; 6687ec681f3Smrg 6697ec681f3Smrg if (cb->logicOpEnable) { 6707ec681f3Smrg state->blend_state.logicop_enable = VK_TRUE; 6717ec681f3Smrg if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_LOGIC_OP_EXT)]) 6727ec681f3Smrg state->blend_state.logicop_func = vk_conv_logic_op(cb->logicOp); 6737ec681f3Smrg } 6747ec681f3Smrg 6757ec681f3Smrg if (cb->attachmentCount > 1) 6767ec681f3Smrg state->blend_state.independent_blend_enable = true; 6777ec681f3Smrg for (i = 0; i < cb->attachmentCount; i++) { 6787ec681f3Smrg state->blend_state.rt[i].colormask = cb->pAttachments[i].colorWriteMask; 6797ec681f3Smrg state->blend_state.rt[i].blend_enable = cb->pAttachments[i].blendEnable; 6807ec681f3Smrg state->blend_state.rt[i].rgb_func = vk_conv_blend_func(cb->pAttachments[i].colorBlendOp); 6817ec681f3Smrg state->blend_state.rt[i].rgb_src_factor = vk_conv_blend_factor(cb->pAttachments[i].srcColorBlendFactor); 6827ec681f3Smrg state->blend_state.rt[i].rgb_dst_factor = vk_conv_blend_factor(cb->pAttachments[i].dstColorBlendFactor); 6837ec681f3Smrg state->blend_state.rt[i].alpha_func = vk_conv_blend_func(cb->pAttachments[i].alphaBlendOp); 6847ec681f3Smrg state->blend_state.rt[i].alpha_src_factor = vk_conv_blend_factor(cb->pAttachments[i].srcAlphaBlendFactor); 6857ec681f3Smrg state->blend_state.rt[i].alpha_dst_factor = vk_conv_blend_factor(cb->pAttachments[i].dstAlphaBlendFactor); 6867ec681f3Smrg 6877ec681f3Smrg /* At least llvmpipe applies the blend factor prior to the blend function, 6887ec681f3Smrg * regardless of what function is used. (like i965 hardware). 6897ec681f3Smrg * It means for MIN/MAX the blend factor has to be stomped to ONE. 6907ec681f3Smrg */ 6917ec681f3Smrg if (cb->pAttachments[i].colorBlendOp == VK_BLEND_OP_MIN || 6927ec681f3Smrg cb->pAttachments[i].colorBlendOp == VK_BLEND_OP_MAX) { 6937ec681f3Smrg state->blend_state.rt[i].rgb_src_factor = PIPE_BLENDFACTOR_ONE; 6947ec681f3Smrg state->blend_state.rt[i].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; 6957ec681f3Smrg } 6967ec681f3Smrg 6977ec681f3Smrg if (cb->pAttachments[i].alphaBlendOp == VK_BLEND_OP_MIN || 6987ec681f3Smrg cb->pAttachments[i].alphaBlendOp == VK_BLEND_OP_MAX) { 6997ec681f3Smrg state->blend_state.rt[i].alpha_src_factor = PIPE_BLENDFACTOR_ONE; 7007ec681f3Smrg state->blend_state.rt[i].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; 7017ec681f3Smrg } 7027ec681f3Smrg } 7037ec681f3Smrg state->blend_dirty = true; 7047ec681f3Smrg if (!dynamic_states[VK_DYNAMIC_STATE_BLEND_CONSTANTS]) { 7057ec681f3Smrg memcpy(state->blend_color.color, cb->blendConstants, 4 * sizeof(float)); 7067ec681f3Smrg state->blend_color_dirty = true; 7077ec681f3Smrg } 7087ec681f3Smrg } else { 7097ec681f3Smrg memset(&state->blend_state, 0, sizeof(state->blend_state)); 7107ec681f3Smrg state->blend_dirty = true; 7117ec681f3Smrg } 7127ec681f3Smrg 7137ec681f3Smrg if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VERTEX_INPUT_EXT)]) { 7147ec681f3Smrg const VkPipelineVertexInputStateCreateInfo *vi = pipeline->graphics_create_info.pVertexInputState; 7157ec681f3Smrg int i; 7167ec681f3Smrg const VkPipelineVertexInputDivisorStateCreateInfoEXT *div_state = 7177ec681f3Smrg vk_find_struct_const(vi->pNext, 7187ec681f3Smrg PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT); 7197ec681f3Smrg 7207ec681f3Smrg if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT)]) { 7217ec681f3Smrg for (i = 0; i < vi->vertexBindingDescriptionCount; i++) { 7227ec681f3Smrg state->vb[vi->pVertexBindingDescriptions[i].binding].stride = vi->pVertexBindingDescriptions[i].stride; 7237ec681f3Smrg } 7247ec681f3Smrg } 7257ec681f3Smrg 7267ec681f3Smrg int max_location = -1; 7277ec681f3Smrg for (i = 0; i < vi->vertexAttributeDescriptionCount; i++) { 7287ec681f3Smrg unsigned location = vi->pVertexAttributeDescriptions[i].location; 7297ec681f3Smrg unsigned binding = vi->pVertexAttributeDescriptions[i].binding; 7307ec681f3Smrg const struct VkVertexInputBindingDescription *desc_binding = NULL; 7317ec681f3Smrg for (unsigned j = 0; j < vi->vertexBindingDescriptionCount; j++) { 7327ec681f3Smrg const struct VkVertexInputBindingDescription *b = &vi->pVertexBindingDescriptions[j]; 7337ec681f3Smrg if (b->binding == binding) { 7347ec681f3Smrg desc_binding = b; 7357ec681f3Smrg break; 7367ec681f3Smrg } 7377ec681f3Smrg } 7387ec681f3Smrg assert(desc_binding); 7397ec681f3Smrg state->velem.velems[location].src_offset = vi->pVertexAttributeDescriptions[i].offset; 7407ec681f3Smrg state->velem.velems[location].vertex_buffer_index = binding; 7417ec681f3Smrg state->velem.velems[location].src_format = lvp_vk_format_to_pipe_format(vi->pVertexAttributeDescriptions[i].format); 7427ec681f3Smrg state->velem.velems[location].dual_slot = false; 7437ec681f3Smrg 7447ec681f3Smrg switch (desc_binding->inputRate) { 7457ec681f3Smrg case VK_VERTEX_INPUT_RATE_VERTEX: 7467ec681f3Smrg state->velem.velems[location].instance_divisor = 0; 7477ec681f3Smrg break; 7487ec681f3Smrg case VK_VERTEX_INPUT_RATE_INSTANCE: 7497ec681f3Smrg if (div_state) { 7507ec681f3Smrg for (unsigned j = 0; j < div_state->vertexBindingDivisorCount; j++) { 7517ec681f3Smrg const VkVertexInputBindingDivisorDescriptionEXT *desc = 7527ec681f3Smrg &div_state->pVertexBindingDivisors[j]; 7537ec681f3Smrg if (desc->binding == state->velem.velems[location].vertex_buffer_index) { 7547ec681f3Smrg state->velem.velems[location].instance_divisor = desc->divisor; 7557ec681f3Smrg break; 7567ec681f3Smrg } 7577ec681f3Smrg } 7587ec681f3Smrg } else 7597ec681f3Smrg state->velem.velems[location].instance_divisor = 1; 7607ec681f3Smrg break; 7617ec681f3Smrg default: 7627ec681f3Smrg assert(0); 7637ec681f3Smrg break; 7647ec681f3Smrg } 7657ec681f3Smrg 7667ec681f3Smrg if ((int)location > max_location) 7677ec681f3Smrg max_location = location; 7687ec681f3Smrg } 7697ec681f3Smrg state->velem.count = max_location + 1; 7707ec681f3Smrg state->vb_dirty = true; 7717ec681f3Smrg state->ve_dirty = true; 7727ec681f3Smrg } 7737ec681f3Smrg 7747ec681f3Smrg { 7757ec681f3Smrg const VkPipelineInputAssemblyStateCreateInfo *ia = pipeline->graphics_create_info.pInputAssemblyState; 7767ec681f3Smrg 7777ec681f3Smrg if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT)]) { 7787ec681f3Smrg state->info.mode = vk_conv_topology(ia->topology); 7797ec681f3Smrg state->rs_dirty = true; 7807ec681f3Smrg } 7817ec681f3Smrg if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT)]) 7827ec681f3Smrg state->info.primitive_restart = ia->primitiveRestartEnable; 7837ec681f3Smrg } 7847ec681f3Smrg 7857ec681f3Smrg if (pipeline->graphics_create_info.pTessellationState) { 7867ec681f3Smrg if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT)]) { 7877ec681f3Smrg const VkPipelineTessellationStateCreateInfo *ts = pipeline->graphics_create_info.pTessellationState; 7887ec681f3Smrg state->patch_vertices = ts->patchControlPoints; 7897ec681f3Smrg } 7907ec681f3Smrg } else 7917ec681f3Smrg state->patch_vertices = 0; 7927ec681f3Smrg 7937ec681f3Smrg if (pipeline->graphics_create_info.pViewportState) { 7947ec681f3Smrg const VkPipelineViewportStateCreateInfo *vpi= pipeline->graphics_create_info.pViewportState; 7957ec681f3Smrg int i; 7967ec681f3Smrg 7977ec681f3Smrg if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT)]) { 7987ec681f3Smrg state->num_viewports = vpi->viewportCount; 7997ec681f3Smrg state->vp_dirty = true; 8007ec681f3Smrg } 8017ec681f3Smrg if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT)]) { 8027ec681f3Smrg state->num_scissors = vpi->scissorCount; 8037ec681f3Smrg state->scissor_dirty = true; 8047ec681f3Smrg } 8057ec681f3Smrg 8067ec681f3Smrg if (!dynamic_states[VK_DYNAMIC_STATE_VIEWPORT] && 8077ec681f3Smrg !dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT)]) { 8087ec681f3Smrg for (i = 0; i < vpi->viewportCount; i++) 8097ec681f3Smrg get_viewport_xform(&vpi->pViewports[i], state->viewports[i].scale, state->viewports[i].translate); 8107ec681f3Smrg state->vp_dirty = true; 8117ec681f3Smrg } 8127ec681f3Smrg if (!dynamic_states[VK_DYNAMIC_STATE_SCISSOR] && 8137ec681f3Smrg !dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT)]) { 8147ec681f3Smrg for (i = 0; i < vpi->scissorCount; i++) { 8157ec681f3Smrg const VkRect2D *ss = &vpi->pScissors[i]; 8167ec681f3Smrg state->scissors[i].minx = ss->offset.x; 8177ec681f3Smrg state->scissors[i].miny = ss->offset.y; 8187ec681f3Smrg state->scissors[i].maxx = ss->offset.x + ss->extent.width; 8197ec681f3Smrg state->scissors[i].maxy = ss->offset.y + ss->extent.height; 8207ec681f3Smrg state->scissor_dirty = true; 8217ec681f3Smrg } 8227ec681f3Smrg 8237ec681f3Smrg } 8247ec681f3Smrg } 8257ec681f3Smrg 8267ec681f3Smrg if (fb_samples != state->framebuffer.samples) { 8277ec681f3Smrg state->framebuffer.samples = fb_samples; 8287ec681f3Smrg state->pctx->set_framebuffer_state(state->pctx, &state->framebuffer); 8297ec681f3Smrg } 8307ec681f3Smrg} 8317ec681f3Smrg 8327ec681f3Smrgstatic void handle_pipeline(struct vk_cmd_queue_entry *cmd, 8337ec681f3Smrg struct rendering_state *state) 8347ec681f3Smrg{ 8357ec681f3Smrg LVP_FROM_HANDLE(lvp_pipeline, pipeline, cmd->u.bind_pipeline.pipeline); 8367ec681f3Smrg if (pipeline->is_compute_pipeline) 8377ec681f3Smrg handle_compute_pipeline(cmd, state); 8387ec681f3Smrg else 8397ec681f3Smrg handle_graphics_pipeline(cmd, state); 8407ec681f3Smrg} 8417ec681f3Smrg 8427ec681f3Smrgstatic void vertex_buffers(uint32_t first_binding, 8437ec681f3Smrg uint32_t binding_count, 8447ec681f3Smrg const VkBuffer *buffers, 8457ec681f3Smrg const VkDeviceSize *offsets, 8467ec681f3Smrg const VkDeviceSize *strides, 8477ec681f3Smrg struct rendering_state *state) 8487ec681f3Smrg{ 8497ec681f3Smrg int i; 8507ec681f3Smrg for (i = 0; i < binding_count; i++) { 8517ec681f3Smrg int idx = i + first_binding; 8527ec681f3Smrg 8537ec681f3Smrg state->vb[idx].buffer_offset = offsets[i]; 8547ec681f3Smrg state->vb[idx].buffer.resource = buffers[i] ? lvp_buffer_from_handle(buffers[i])->bo : NULL; 8557ec681f3Smrg 8567ec681f3Smrg if (strides) 8577ec681f3Smrg state->vb[idx].stride = strides[i]; 8587ec681f3Smrg } 8597ec681f3Smrg if (first_binding < state->start_vb) 8607ec681f3Smrg state->start_vb = first_binding; 8617ec681f3Smrg if (first_binding + binding_count >= state->num_vb) 8627ec681f3Smrg state->num_vb = first_binding + binding_count; 8637ec681f3Smrg state->vb_dirty = true; 8647ec681f3Smrg} 8657ec681f3Smrg 8667ec681f3Smrgstatic void handle_vertex_buffers(struct vk_cmd_queue_entry *cmd, 8677ec681f3Smrg struct rendering_state *state) 8687ec681f3Smrg{ 8697ec681f3Smrg struct vk_cmd_bind_vertex_buffers *vcb = &cmd->u.bind_vertex_buffers; 8707ec681f3Smrg 8717ec681f3Smrg vertex_buffers(vcb->first_binding, 8727ec681f3Smrg vcb->binding_count, 8737ec681f3Smrg vcb->buffers, 8747ec681f3Smrg vcb->offsets, 8757ec681f3Smrg NULL, 8767ec681f3Smrg state); 8777ec681f3Smrg} 8787ec681f3Smrg 8797ec681f3Smrgstatic void handle_vertex_buffers2(struct vk_cmd_queue_entry *cmd, 8807ec681f3Smrg struct rendering_state *state) 8817ec681f3Smrg{ 8827ec681f3Smrg struct vk_cmd_bind_vertex_buffers2_ext *vcb = &cmd->u.bind_vertex_buffers2_ext; 8837ec681f3Smrg 8847ec681f3Smrg vertex_buffers(vcb->first_binding, 8857ec681f3Smrg vcb->binding_count, 8867ec681f3Smrg vcb->buffers, 8877ec681f3Smrg vcb->offsets, 8887ec681f3Smrg vcb->strides, 8897ec681f3Smrg state); 8907ec681f3Smrg} 8917ec681f3Smrg 8927ec681f3Smrgstruct dyn_info { 8937ec681f3Smrg struct { 8947ec681f3Smrg uint16_t const_buffer_count; 8957ec681f3Smrg uint16_t shader_buffer_count; 8967ec681f3Smrg uint16_t sampler_count; 8977ec681f3Smrg uint16_t sampler_view_count; 8987ec681f3Smrg uint16_t image_count; 8997ec681f3Smrg } stage[MESA_SHADER_STAGES]; 9007ec681f3Smrg 9017ec681f3Smrg uint32_t dyn_index; 9027ec681f3Smrg const uint32_t *dynamic_offsets; 9037ec681f3Smrg uint32_t dynamic_offset_count; 9047ec681f3Smrg}; 9057ec681f3Smrg 9067ec681f3Smrgstatic void fill_sampler(struct pipe_sampler_state *ss, 9077ec681f3Smrg struct lvp_sampler *samp) 9087ec681f3Smrg{ 9097ec681f3Smrg ss->wrap_s = vk_conv_wrap_mode(samp->create_info.addressModeU); 9107ec681f3Smrg ss->wrap_t = vk_conv_wrap_mode(samp->create_info.addressModeV); 9117ec681f3Smrg ss->wrap_r = vk_conv_wrap_mode(samp->create_info.addressModeW); 9127ec681f3Smrg ss->min_img_filter = samp->create_info.minFilter == VK_FILTER_LINEAR ? PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST; 9137ec681f3Smrg ss->min_mip_filter = samp->create_info.mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR ? PIPE_TEX_MIPFILTER_LINEAR : PIPE_TEX_MIPFILTER_NEAREST; 9147ec681f3Smrg ss->mag_img_filter = samp->create_info.magFilter == VK_FILTER_LINEAR ? PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST; 9157ec681f3Smrg ss->min_lod = samp->create_info.minLod; 9167ec681f3Smrg ss->max_lod = samp->create_info.maxLod; 9177ec681f3Smrg ss->lod_bias = samp->create_info.mipLodBias; 9187ec681f3Smrg if (samp->create_info.anisotropyEnable) 9197ec681f3Smrg ss->max_anisotropy = samp->create_info.maxAnisotropy; 9207ec681f3Smrg else 9217ec681f3Smrg ss->max_anisotropy = 1; 9227ec681f3Smrg ss->normalized_coords = !samp->create_info.unnormalizedCoordinates; 9237ec681f3Smrg ss->compare_mode = samp->create_info.compareEnable ? PIPE_TEX_COMPARE_R_TO_TEXTURE : PIPE_TEX_COMPARE_NONE; 9247ec681f3Smrg ss->compare_func = samp->create_info.compareOp; 9257ec681f3Smrg ss->seamless_cube_map = true; 9267ec681f3Smrg ss->reduction_mode = samp->reduction_mode; 9277ec681f3Smrg memcpy(&ss->border_color, &samp->border_color, 9287ec681f3Smrg sizeof(union pipe_color_union)); 9297ec681f3Smrg} 9307ec681f3Smrg 9317ec681f3Smrgstatic void fill_sampler_stage(struct rendering_state *state, 9327ec681f3Smrg struct dyn_info *dyn_info, 9337ec681f3Smrg gl_shader_stage stage, 9347ec681f3Smrg enum pipe_shader_type p_stage, 9357ec681f3Smrg int array_idx, 9367ec681f3Smrg const union lvp_descriptor_info *descriptor, 9377ec681f3Smrg const struct lvp_descriptor_set_binding_layout *binding) 9387ec681f3Smrg{ 9397ec681f3Smrg int ss_idx = binding->stage[stage].sampler_index; 9407ec681f3Smrg if (ss_idx == -1) 9417ec681f3Smrg return; 9427ec681f3Smrg ss_idx += array_idx; 9437ec681f3Smrg ss_idx += dyn_info->stage[stage].sampler_count; 9447ec681f3Smrg fill_sampler(&state->ss[p_stage][ss_idx], binding->immutable_samplers ? binding->immutable_samplers[array_idx] : descriptor->sampler); 9457ec681f3Smrg if (state->num_sampler_states[p_stage] <= ss_idx) 9467ec681f3Smrg state->num_sampler_states[p_stage] = ss_idx + 1; 9477ec681f3Smrg state->ss_dirty[p_stage] = true; 9487ec681f3Smrg} 9497ec681f3Smrg 9507ec681f3Smrg#define fix_depth_swizzle(x) do { \ 9517ec681f3Smrg if (x > PIPE_SWIZZLE_X && x < PIPE_SWIZZLE_0) \ 9527ec681f3Smrg x = PIPE_SWIZZLE_0; \ 9537ec681f3Smrg } while (0) 9547ec681f3Smrg#define fix_depth_swizzle_a(x) do { \ 9557ec681f3Smrg if (x > PIPE_SWIZZLE_X && x < PIPE_SWIZZLE_0) \ 9567ec681f3Smrg x = PIPE_SWIZZLE_1; \ 9577ec681f3Smrg } while (0) 9587ec681f3Smrg 9597ec681f3Smrgstatic void fill_sampler_view_stage(struct rendering_state *state, 9607ec681f3Smrg struct dyn_info *dyn_info, 9617ec681f3Smrg gl_shader_stage stage, 9627ec681f3Smrg enum pipe_shader_type p_stage, 9637ec681f3Smrg int array_idx, 9647ec681f3Smrg const union lvp_descriptor_info *descriptor, 9657ec681f3Smrg const struct lvp_descriptor_set_binding_layout *binding) 9667ec681f3Smrg{ 9677ec681f3Smrg int sv_idx = binding->stage[stage].sampler_view_index; 9687ec681f3Smrg if (sv_idx == -1) 9697ec681f3Smrg return; 9707ec681f3Smrg sv_idx += array_idx; 9717ec681f3Smrg sv_idx += dyn_info->stage[stage].sampler_view_count; 9727ec681f3Smrg struct lvp_image_view *iv = descriptor->iview; 9737ec681f3Smrg struct pipe_sampler_view templ; 9747ec681f3Smrg 9757ec681f3Smrg enum pipe_format pformat; 9767ec681f3Smrg if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) 9777ec681f3Smrg pformat = lvp_vk_format_to_pipe_format(iv->format); 9787ec681f3Smrg else if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) 9797ec681f3Smrg pformat = util_format_stencil_only(lvp_vk_format_to_pipe_format(iv->format)); 9807ec681f3Smrg else 9817ec681f3Smrg pformat = lvp_vk_format_to_pipe_format(iv->format); 9827ec681f3Smrg u_sampler_view_default_template(&templ, 9837ec681f3Smrg iv->image->bo, 9847ec681f3Smrg pformat); 9857ec681f3Smrg if (iv->view_type == VK_IMAGE_VIEW_TYPE_1D) 9867ec681f3Smrg templ.target = PIPE_TEXTURE_1D; 9877ec681f3Smrg if (iv->view_type == VK_IMAGE_VIEW_TYPE_2D) 9887ec681f3Smrg templ.target = PIPE_TEXTURE_2D; 9897ec681f3Smrg if (iv->view_type == VK_IMAGE_VIEW_TYPE_CUBE) 9907ec681f3Smrg templ.target = PIPE_TEXTURE_CUBE; 9917ec681f3Smrg if (iv->view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) 9927ec681f3Smrg templ.target = PIPE_TEXTURE_CUBE_ARRAY; 9937ec681f3Smrg templ.u.tex.first_layer = iv->subresourceRange.baseArrayLayer; 9947ec681f3Smrg templ.u.tex.last_layer = iv->subresourceRange.baseArrayLayer + lvp_get_layerCount(iv->image, &iv->subresourceRange) - 1; 9957ec681f3Smrg templ.u.tex.first_level = iv->subresourceRange.baseMipLevel; 9967ec681f3Smrg templ.u.tex.last_level = iv->subresourceRange.baseMipLevel + lvp_get_levelCount(iv->image, &iv->subresourceRange) - 1; 9977ec681f3Smrg if (iv->components.r != VK_COMPONENT_SWIZZLE_IDENTITY) 9987ec681f3Smrg templ.swizzle_r = vk_conv_swizzle(iv->components.r); 9997ec681f3Smrg if (iv->components.g != VK_COMPONENT_SWIZZLE_IDENTITY) 10007ec681f3Smrg templ.swizzle_g = vk_conv_swizzle(iv->components.g); 10017ec681f3Smrg if (iv->components.b != VK_COMPONENT_SWIZZLE_IDENTITY) 10027ec681f3Smrg templ.swizzle_b = vk_conv_swizzle(iv->components.b); 10037ec681f3Smrg if (iv->components.a != VK_COMPONENT_SWIZZLE_IDENTITY) 10047ec681f3Smrg templ.swizzle_a = vk_conv_swizzle(iv->components.a); 10057ec681f3Smrg 10067ec681f3Smrg /* depth stencil swizzles need special handling to pass VK CTS 10077ec681f3Smrg * but also for zink GL tests. 10087ec681f3Smrg * piping A swizzle into R fixes GL_ALPHA depth texture mode 10097ec681f3Smrg * only swizzling from R/0/1 (for alpha) fixes VK CTS tests 10107ec681f3Smrg * and a bunch of zink tests. 10117ec681f3Smrg */ 10127ec681f3Smrg if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT || 10137ec681f3Smrg iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) { 10147ec681f3Smrg if (templ.swizzle_a == PIPE_SWIZZLE_X) 10157ec681f3Smrg templ.swizzle_r = PIPE_SWIZZLE_X; 10167ec681f3Smrg fix_depth_swizzle(templ.swizzle_r); 10177ec681f3Smrg fix_depth_swizzle(templ.swizzle_g); 10187ec681f3Smrg fix_depth_swizzle(templ.swizzle_b); 10197ec681f3Smrg fix_depth_swizzle_a(templ.swizzle_a); 10207ec681f3Smrg } 10217ec681f3Smrg 10227ec681f3Smrg if (state->sv[p_stage][sv_idx]) 10237ec681f3Smrg pipe_sampler_view_reference(&state->sv[p_stage][sv_idx], NULL); 10247ec681f3Smrg state->sv[p_stage][sv_idx] = state->pctx->create_sampler_view(state->pctx, iv->image->bo, &templ); 10257ec681f3Smrg if (state->num_sampler_views[p_stage] <= sv_idx) 10267ec681f3Smrg state->num_sampler_views[p_stage] = sv_idx + 1; 10277ec681f3Smrg state->sv_dirty[p_stage] = true; 10287ec681f3Smrg} 10297ec681f3Smrg 10307ec681f3Smrgstatic void fill_sampler_buffer_view_stage(struct rendering_state *state, 10317ec681f3Smrg struct dyn_info *dyn_info, 10327ec681f3Smrg gl_shader_stage stage, 10337ec681f3Smrg enum pipe_shader_type p_stage, 10347ec681f3Smrg int array_idx, 10357ec681f3Smrg const union lvp_descriptor_info *descriptor, 10367ec681f3Smrg const struct lvp_descriptor_set_binding_layout *binding) 10377ec681f3Smrg{ 10387ec681f3Smrg int sv_idx = binding->stage[stage].sampler_view_index; 10397ec681f3Smrg if (sv_idx == -1) 10407ec681f3Smrg return; 10417ec681f3Smrg sv_idx += array_idx; 10427ec681f3Smrg sv_idx += dyn_info->stage[stage].sampler_view_count; 10437ec681f3Smrg struct lvp_buffer_view *bv = descriptor->buffer_view; 10447ec681f3Smrg struct pipe_sampler_view templ; 10457ec681f3Smrg memset(&templ, 0, sizeof(templ)); 10467ec681f3Smrg templ.target = PIPE_BUFFER; 10477ec681f3Smrg templ.swizzle_r = PIPE_SWIZZLE_X; 10487ec681f3Smrg templ.swizzle_g = PIPE_SWIZZLE_Y; 10497ec681f3Smrg templ.swizzle_b = PIPE_SWIZZLE_Z; 10507ec681f3Smrg templ.swizzle_a = PIPE_SWIZZLE_W; 10517ec681f3Smrg templ.format = bv->pformat; 10527ec681f3Smrg templ.u.buf.offset = bv->offset + bv->buffer->offset; 10537ec681f3Smrg templ.u.buf.size = bv->range == VK_WHOLE_SIZE ? (bv->buffer->size - bv->offset) : bv->range; 10547ec681f3Smrg templ.texture = bv->buffer->bo; 10557ec681f3Smrg templ.context = state->pctx; 10567ec681f3Smrg 10577ec681f3Smrg if (state->sv[p_stage][sv_idx]) 10587ec681f3Smrg pipe_sampler_view_reference(&state->sv[p_stage][sv_idx], NULL); 10597ec681f3Smrg state->sv[p_stage][sv_idx] = state->pctx->create_sampler_view(state->pctx, bv->buffer->bo, &templ); 10607ec681f3Smrg if (state->num_sampler_views[p_stage] <= sv_idx) 10617ec681f3Smrg state->num_sampler_views[p_stage] = sv_idx + 1; 10627ec681f3Smrg state->sv_dirty[p_stage] = true; 10637ec681f3Smrg} 10647ec681f3Smrg 10657ec681f3Smrgstatic void fill_image_view_stage(struct rendering_state *state, 10667ec681f3Smrg struct dyn_info *dyn_info, 10677ec681f3Smrg gl_shader_stage stage, 10687ec681f3Smrg enum pipe_shader_type p_stage, 10697ec681f3Smrg int array_idx, 10707ec681f3Smrg const union lvp_descriptor_info *descriptor, 10717ec681f3Smrg const struct lvp_descriptor_set_binding_layout *binding) 10727ec681f3Smrg{ 10737ec681f3Smrg struct lvp_image_view *iv = descriptor->iview; 10747ec681f3Smrg int idx = binding->stage[stage].image_index; 10757ec681f3Smrg if (idx == -1) 10767ec681f3Smrg return; 10777ec681f3Smrg idx += array_idx; 10787ec681f3Smrg idx += dyn_info->stage[stage].image_count; 10797ec681f3Smrg state->iv[p_stage][idx].resource = iv->image->bo; 10807ec681f3Smrg if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) 10817ec681f3Smrg state->iv[p_stage][idx].format = lvp_vk_format_to_pipe_format(iv->format); 10827ec681f3Smrg else if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) 10837ec681f3Smrg state->iv[p_stage][idx].format = util_format_stencil_only(lvp_vk_format_to_pipe_format(iv->format)); 10847ec681f3Smrg else 10857ec681f3Smrg state->iv[p_stage][idx].format = lvp_vk_format_to_pipe_format(iv->format); 10867ec681f3Smrg 10877ec681f3Smrg if (iv->view_type == VK_IMAGE_VIEW_TYPE_3D) { 10887ec681f3Smrg state->iv[p_stage][idx].u.tex.first_layer = 0; 10897ec681f3Smrg state->iv[p_stage][idx].u.tex.last_layer = u_minify(iv->image->bo->depth0, iv->subresourceRange.baseMipLevel) - 1; 10907ec681f3Smrg } else { 10917ec681f3Smrg state->iv[p_stage][idx].u.tex.first_layer = iv->subresourceRange.baseArrayLayer; 10927ec681f3Smrg state->iv[p_stage][idx].u.tex.last_layer = iv->subresourceRange.baseArrayLayer + lvp_get_layerCount(iv->image, &iv->subresourceRange) - 1; 10937ec681f3Smrg } 10947ec681f3Smrg state->iv[p_stage][idx].u.tex.level = iv->subresourceRange.baseMipLevel; 10957ec681f3Smrg if (state->num_shader_images[p_stage] <= idx) 10967ec681f3Smrg state->num_shader_images[p_stage] = idx + 1; 10977ec681f3Smrg state->iv_dirty[p_stage] = true; 10987ec681f3Smrg} 10997ec681f3Smrg 11007ec681f3Smrgstatic void fill_image_buffer_view_stage(struct rendering_state *state, 11017ec681f3Smrg struct dyn_info *dyn_info, 11027ec681f3Smrg gl_shader_stage stage, 11037ec681f3Smrg enum pipe_shader_type p_stage, 11047ec681f3Smrg int array_idx, 11057ec681f3Smrg const union lvp_descriptor_info *descriptor, 11067ec681f3Smrg const struct lvp_descriptor_set_binding_layout *binding) 11077ec681f3Smrg{ 11087ec681f3Smrg struct lvp_buffer_view *bv = descriptor->buffer_view; 11097ec681f3Smrg int idx = binding->stage[stage].image_index; 11107ec681f3Smrg if (idx == -1) 11117ec681f3Smrg return; 11127ec681f3Smrg idx += array_idx; 11137ec681f3Smrg idx += dyn_info->stage[stage].image_count; 11147ec681f3Smrg state->iv[p_stage][idx].resource = bv->buffer->bo; 11157ec681f3Smrg state->iv[p_stage][idx].format = bv->pformat; 11167ec681f3Smrg state->iv[p_stage][idx].u.buf.offset = bv->offset + bv->buffer->offset; 11177ec681f3Smrg state->iv[p_stage][idx].u.buf.size = bv->range == VK_WHOLE_SIZE ? (bv->buffer->size - bv->offset): bv->range; 11187ec681f3Smrg if (state->num_shader_images[p_stage] <= idx) 11197ec681f3Smrg state->num_shader_images[p_stage] = idx + 1; 11207ec681f3Smrg state->iv_dirty[p_stage] = true; 11217ec681f3Smrg} 11227ec681f3Smrg 11237ec681f3Smrgstatic void handle_descriptor(struct rendering_state *state, 11247ec681f3Smrg struct dyn_info *dyn_info, 11257ec681f3Smrg const struct lvp_descriptor_set_binding_layout *binding, 11267ec681f3Smrg gl_shader_stage stage, 11277ec681f3Smrg enum pipe_shader_type p_stage, 11287ec681f3Smrg int array_idx, 11297ec681f3Smrg VkDescriptorType type, 11307ec681f3Smrg const union lvp_descriptor_info *descriptor) 11317ec681f3Smrg{ 11327ec681f3Smrg bool is_dynamic = type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || 11337ec681f3Smrg type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; 11347ec681f3Smrg 11357ec681f3Smrg switch (type) { 11367ec681f3Smrg case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 11377ec681f3Smrg case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: { 11387ec681f3Smrg fill_image_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding); 11397ec681f3Smrg break; 11407ec681f3Smrg } 11417ec681f3Smrg case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 11427ec681f3Smrg case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: { 11437ec681f3Smrg int idx = binding->stage[stage].const_buffer_index; 11447ec681f3Smrg if (idx == -1) 11457ec681f3Smrg return; 11467ec681f3Smrg idx += array_idx; 11477ec681f3Smrg idx += dyn_info->stage[stage].const_buffer_count; 11487ec681f3Smrg state->const_buffer[p_stage][idx].buffer = descriptor->buffer->bo; 11497ec681f3Smrg state->const_buffer[p_stage][idx].buffer_offset = descriptor->offset + descriptor->buffer->offset; 11507ec681f3Smrg if (is_dynamic) { 11517ec681f3Smrg uint32_t offset = dyn_info->dynamic_offsets[dyn_info->dyn_index + binding->dynamic_index + array_idx]; 11527ec681f3Smrg state->const_buffer[p_stage][idx].buffer_offset += offset; 11537ec681f3Smrg } 11547ec681f3Smrg if (descriptor->range == VK_WHOLE_SIZE) 11557ec681f3Smrg state->const_buffer[p_stage][idx].buffer_size = descriptor->buffer->bo->width0 - state->const_buffer[p_stage][idx].buffer_offset; 11567ec681f3Smrg else 11577ec681f3Smrg state->const_buffer[p_stage][idx].buffer_size = descriptor->range; 11587ec681f3Smrg if (state->num_const_bufs[p_stage] <= idx) 11597ec681f3Smrg state->num_const_bufs[p_stage] = idx + 1; 11607ec681f3Smrg state->constbuf_dirty[p_stage] = true; 11617ec681f3Smrg break; 11627ec681f3Smrg } 11637ec681f3Smrg case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 11647ec681f3Smrg case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: { 11657ec681f3Smrg int idx = binding->stage[stage].shader_buffer_index; 11667ec681f3Smrg if (idx == -1) 11677ec681f3Smrg return; 11687ec681f3Smrg idx += array_idx; 11697ec681f3Smrg idx += dyn_info->stage[stage].shader_buffer_count; 11707ec681f3Smrg state->sb[p_stage][idx].buffer = descriptor->buffer->bo; 11717ec681f3Smrg state->sb[p_stage][idx].buffer_offset = descriptor->offset + descriptor->buffer->offset; 11727ec681f3Smrg if (is_dynamic) { 11737ec681f3Smrg uint32_t offset = dyn_info->dynamic_offsets[dyn_info->dyn_index + binding->dynamic_index + array_idx]; 11747ec681f3Smrg state->sb[p_stage][idx].buffer_offset += offset; 11757ec681f3Smrg } 11767ec681f3Smrg if (descriptor->range == VK_WHOLE_SIZE) 11777ec681f3Smrg state->sb[p_stage][idx].buffer_size = descriptor->buffer->bo->width0 - state->sb[p_stage][idx].buffer_offset; 11787ec681f3Smrg else 11797ec681f3Smrg state->sb[p_stage][idx].buffer_size = descriptor->range; 11807ec681f3Smrg if (state->num_shader_buffers[p_stage] <= idx) 11817ec681f3Smrg state->num_shader_buffers[p_stage] = idx + 1; 11827ec681f3Smrg state->sb_dirty[p_stage] = true; 11837ec681f3Smrg break; 11847ec681f3Smrg } 11857ec681f3Smrg case VK_DESCRIPTOR_TYPE_SAMPLER: 11867ec681f3Smrg if (!descriptor->sampler) 11877ec681f3Smrg return; 11887ec681f3Smrg fill_sampler_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding); 11897ec681f3Smrg break; 11907ec681f3Smrg case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 11917ec681f3Smrg fill_sampler_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding); 11927ec681f3Smrg break; 11937ec681f3Smrg case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 11947ec681f3Smrg fill_sampler_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding); 11957ec681f3Smrg fill_sampler_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding); 11967ec681f3Smrg break; 11977ec681f3Smrg case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 11987ec681f3Smrg fill_sampler_buffer_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding); 11997ec681f3Smrg break; 12007ec681f3Smrg case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 12017ec681f3Smrg fill_image_buffer_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding); 12027ec681f3Smrg break; 12037ec681f3Smrg default: 12047ec681f3Smrg fprintf(stderr, "Unhandled descriptor set %d\n", type); 12057ec681f3Smrg break; 12067ec681f3Smrg } 12077ec681f3Smrg} 12087ec681f3Smrg 12097ec681f3Smrgstatic void handle_set_stage(struct rendering_state *state, 12107ec681f3Smrg struct dyn_info *dyn_info, 12117ec681f3Smrg const struct lvp_descriptor_set *set, 12127ec681f3Smrg gl_shader_stage stage, 12137ec681f3Smrg enum pipe_shader_type p_stage) 12147ec681f3Smrg{ 12157ec681f3Smrg int j; 12167ec681f3Smrg for (j = 0; j < set->layout->binding_count; j++) { 12177ec681f3Smrg const struct lvp_descriptor_set_binding_layout *binding; 12187ec681f3Smrg const struct lvp_descriptor *descriptor; 12197ec681f3Smrg binding = &set->layout->binding[j]; 12207ec681f3Smrg 12217ec681f3Smrg if (binding->valid) { 12227ec681f3Smrg for (int i = 0; i < binding->array_size; i++) { 12237ec681f3Smrg descriptor = &set->descriptors[binding->descriptor_index + i]; 12247ec681f3Smrg handle_descriptor(state, dyn_info, binding, stage, p_stage, i, descriptor->type, &descriptor->info); 12257ec681f3Smrg } 12267ec681f3Smrg } 12277ec681f3Smrg } 12287ec681f3Smrg} 12297ec681f3Smrg 12307ec681f3Smrgstatic void increment_dyn_info(struct dyn_info *dyn_info, 12317ec681f3Smrg struct lvp_descriptor_set_layout *layout, bool inc_dyn) 12327ec681f3Smrg{ 12337ec681f3Smrg for (gl_shader_stage stage = MESA_SHADER_VERTEX; stage < MESA_SHADER_STAGES; stage++) { 12347ec681f3Smrg dyn_info->stage[stage].const_buffer_count += layout->stage[stage].const_buffer_count; 12357ec681f3Smrg dyn_info->stage[stage].shader_buffer_count += layout->stage[stage].shader_buffer_count; 12367ec681f3Smrg dyn_info->stage[stage].sampler_count += layout->stage[stage].sampler_count; 12377ec681f3Smrg dyn_info->stage[stage].sampler_view_count += layout->stage[stage].sampler_view_count; 12387ec681f3Smrg dyn_info->stage[stage].image_count += layout->stage[stage].image_count; 12397ec681f3Smrg } 12407ec681f3Smrg if (inc_dyn) 12417ec681f3Smrg dyn_info->dyn_index += layout->dynamic_offset_count; 12427ec681f3Smrg} 12437ec681f3Smrg 12447ec681f3Smrgstatic void handle_compute_descriptor_sets(struct vk_cmd_queue_entry *cmd, 12457ec681f3Smrg struct dyn_info *dyn_info, 12467ec681f3Smrg struct rendering_state *state) 12477ec681f3Smrg{ 12487ec681f3Smrg struct vk_cmd_bind_descriptor_sets *bds = &cmd->u.bind_descriptor_sets; 12497ec681f3Smrg struct lvp_descriptor_set_layout **set_layout = cmd->driver_data; 12507ec681f3Smrg int i; 12517ec681f3Smrg 12527ec681f3Smrg for (i = 0; i < bds->first_set; i++) { 12537ec681f3Smrg increment_dyn_info(dyn_info, set_layout[i], false); 12547ec681f3Smrg } 12557ec681f3Smrg for (i = 0; i < bds->descriptor_set_count; i++) { 12567ec681f3Smrg const struct lvp_descriptor_set *set = lvp_descriptor_set_from_handle(bds->descriptor_sets[i]); 12577ec681f3Smrg 12587ec681f3Smrg if (set->layout->shader_stages & VK_SHADER_STAGE_COMPUTE_BIT) 12597ec681f3Smrg handle_set_stage(state, dyn_info, set, MESA_SHADER_COMPUTE, PIPE_SHADER_COMPUTE); 12607ec681f3Smrg increment_dyn_info(dyn_info, set_layout[bds->first_set + i], true); 12617ec681f3Smrg } 12627ec681f3Smrg} 12637ec681f3Smrg 12647ec681f3Smrgstatic void handle_descriptor_sets(struct vk_cmd_queue_entry *cmd, 12657ec681f3Smrg struct rendering_state *state) 12667ec681f3Smrg{ 12677ec681f3Smrg struct vk_cmd_bind_descriptor_sets *bds = &cmd->u.bind_descriptor_sets; 12687ec681f3Smrg struct lvp_descriptor_set_layout **set_layout = cmd->driver_data; 12697ec681f3Smrg int i; 12707ec681f3Smrg struct dyn_info dyn_info; 12717ec681f3Smrg 12727ec681f3Smrg dyn_info.dyn_index = 0; 12737ec681f3Smrg dyn_info.dynamic_offsets = bds->dynamic_offsets; 12747ec681f3Smrg dyn_info.dynamic_offset_count = bds->dynamic_offset_count; 12757ec681f3Smrg 12767ec681f3Smrg memset(dyn_info.stage, 0, sizeof(dyn_info.stage)); 12777ec681f3Smrg if (bds->pipeline_bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) { 12787ec681f3Smrg handle_compute_descriptor_sets(cmd, &dyn_info, state); 12797ec681f3Smrg return; 12807ec681f3Smrg } 12817ec681f3Smrg 12827ec681f3Smrg for (i = 0; i < bds->first_set; i++) { 12837ec681f3Smrg increment_dyn_info(&dyn_info, set_layout[i], false); 12847ec681f3Smrg } 12857ec681f3Smrg 12867ec681f3Smrg for (i = 0; i < bds->descriptor_set_count; i++) { 12877ec681f3Smrg const struct lvp_descriptor_set *set = lvp_descriptor_set_from_handle(bds->descriptor_sets[i]); 12887ec681f3Smrg 12897ec681f3Smrg if (set->layout->shader_stages & VK_SHADER_STAGE_VERTEX_BIT) 12907ec681f3Smrg handle_set_stage(state, &dyn_info, set, MESA_SHADER_VERTEX, PIPE_SHADER_VERTEX); 12917ec681f3Smrg 12927ec681f3Smrg if (set->layout->shader_stages & VK_SHADER_STAGE_GEOMETRY_BIT) 12937ec681f3Smrg handle_set_stage(state, &dyn_info, set, MESA_SHADER_GEOMETRY, PIPE_SHADER_GEOMETRY); 12947ec681f3Smrg 12957ec681f3Smrg if (set->layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) 12967ec681f3Smrg handle_set_stage(state, &dyn_info, set, MESA_SHADER_TESS_CTRL, PIPE_SHADER_TESS_CTRL); 12977ec681f3Smrg 12987ec681f3Smrg if (set->layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) 12997ec681f3Smrg handle_set_stage(state, &dyn_info, set, MESA_SHADER_TESS_EVAL, PIPE_SHADER_TESS_EVAL); 13007ec681f3Smrg 13017ec681f3Smrg if (set->layout->shader_stages & VK_SHADER_STAGE_FRAGMENT_BIT) 13027ec681f3Smrg handle_set_stage(state, &dyn_info, set, MESA_SHADER_FRAGMENT, PIPE_SHADER_FRAGMENT); 13037ec681f3Smrg 13047ec681f3Smrg increment_dyn_info(&dyn_info, set_layout[bds->first_set + i], true); 13057ec681f3Smrg } 13067ec681f3Smrg} 13077ec681f3Smrg 13087ec681f3Smrgstatic struct pipe_surface *create_img_surface_bo(struct rendering_state *state, 13097ec681f3Smrg VkImageSubresourceRange *range, 13107ec681f3Smrg struct pipe_resource *bo, 13117ec681f3Smrg enum pipe_format pformat, 13127ec681f3Smrg int width, 13137ec681f3Smrg int height, 13147ec681f3Smrg int base_layer, int layer_count, 13157ec681f3Smrg int level) 13167ec681f3Smrg{ 13177ec681f3Smrg struct pipe_surface template; 13187ec681f3Smrg 13197ec681f3Smrg memset(&template, 0, sizeof(struct pipe_surface)); 13207ec681f3Smrg 13217ec681f3Smrg template.format = pformat; 13227ec681f3Smrg template.width = width; 13237ec681f3Smrg template.height = height; 13247ec681f3Smrg template.u.tex.first_layer = range->baseArrayLayer + base_layer; 13257ec681f3Smrg template.u.tex.last_layer = range->baseArrayLayer + layer_count; 13267ec681f3Smrg template.u.tex.level = range->baseMipLevel + level; 13277ec681f3Smrg 13287ec681f3Smrg if (template.format == PIPE_FORMAT_NONE) 13297ec681f3Smrg return NULL; 13307ec681f3Smrg return state->pctx->create_surface(state->pctx, 13317ec681f3Smrg bo, &template); 13327ec681f3Smrg 13337ec681f3Smrg} 13347ec681f3Smrgstatic struct pipe_surface *create_img_surface(struct rendering_state *state, 13357ec681f3Smrg struct lvp_image_view *imgv, 13367ec681f3Smrg VkFormat format, int width, 13377ec681f3Smrg int height, 13387ec681f3Smrg int base_layer, int layer_count) 13397ec681f3Smrg{ 13407ec681f3Smrg return create_img_surface_bo(state, &imgv->subresourceRange, imgv->image->bo, 13417ec681f3Smrg lvp_vk_format_to_pipe_format(format), width, height, base_layer, layer_count, 0); 13427ec681f3Smrg} 13437ec681f3Smrg 13447ec681f3Smrgstatic void add_img_view_surface(struct rendering_state *state, 13457ec681f3Smrg struct lvp_image_view *imgv, VkFormat format, int width, int height) 13467ec681f3Smrg{ 13477ec681f3Smrg if (!imgv->surface) { 13487ec681f3Smrg imgv->surface = create_img_surface(state, imgv, format, 13497ec681f3Smrg width, height, 13507ec681f3Smrg 0, lvp_get_layerCount(imgv->image, &imgv->subresourceRange) - 1); 13517ec681f3Smrg } 13527ec681f3Smrg} 13537ec681f3Smrg 13547ec681f3Smrgstatic inline bool 13557ec681f3Smrgattachment_needs_clear(struct rendering_state *state, 13567ec681f3Smrg uint32_t a) 13577ec681f3Smrg{ 13587ec681f3Smrg const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass]; 13597ec681f3Smrg uint32_t view_mask = subpass->view_mask; 13607ec681f3Smrg return (a != VK_ATTACHMENT_UNUSED && 13617ec681f3Smrg state->pending_clear_aspects[a] && 13627ec681f3Smrg (!view_mask || (view_mask & ~state->cleared_views[a]))); 13637ec681f3Smrg} 13647ec681f3Smrg 13657ec681f3Smrgstatic bool 13667ec681f3Smrgsubpass_needs_clear(struct rendering_state *state) 13677ec681f3Smrg{ 13687ec681f3Smrg uint32_t a; 13697ec681f3Smrg const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass]; 13707ec681f3Smrg for (uint32_t i = 0; i < subpass->color_count; i++) { 13717ec681f3Smrg a = subpass->color_attachments[i].attachment; 13727ec681f3Smrg if (attachment_needs_clear(state, a)) 13737ec681f3Smrg return true; 13747ec681f3Smrg } 13757ec681f3Smrg if (subpass->depth_stencil_attachment) { 13767ec681f3Smrg a = subpass->depth_stencil_attachment->attachment; 13777ec681f3Smrg if (attachment_needs_clear(state, a)) 13787ec681f3Smrg return true; 13797ec681f3Smrg } 13807ec681f3Smrg return false; 13817ec681f3Smrg} 13827ec681f3Smrg 13837ec681f3Smrgstatic void clear_attachment_layers(struct rendering_state *state, 13847ec681f3Smrg struct lvp_image_view *imgv, 13857ec681f3Smrg VkRect2D *rect, 13867ec681f3Smrg unsigned base_layer, unsigned layer_count, 13877ec681f3Smrg unsigned ds_clear_flags, double dclear_val, 13887ec681f3Smrg uint32_t sclear_val, 13897ec681f3Smrg union pipe_color_union *col_val) 13907ec681f3Smrg{ 13917ec681f3Smrg struct pipe_surface *clear_surf = create_img_surface(state, 13927ec681f3Smrg imgv, 13937ec681f3Smrg imgv->format, 13947ec681f3Smrg state->framebuffer.width, 13957ec681f3Smrg state->framebuffer.height, 13967ec681f3Smrg base_layer, 13977ec681f3Smrg base_layer + layer_count - 1); 13987ec681f3Smrg 13997ec681f3Smrg if (ds_clear_flags) { 14007ec681f3Smrg state->pctx->clear_depth_stencil(state->pctx, 14017ec681f3Smrg clear_surf, 14027ec681f3Smrg ds_clear_flags, 14037ec681f3Smrg dclear_val, sclear_val, 14047ec681f3Smrg rect->offset.x, rect->offset.y, 14057ec681f3Smrg rect->extent.width, rect->extent.height, 14067ec681f3Smrg true); 14077ec681f3Smrg } else { 14087ec681f3Smrg state->pctx->clear_render_target(state->pctx, clear_surf, 14097ec681f3Smrg col_val, 14107ec681f3Smrg rect->offset.x, rect->offset.y, 14117ec681f3Smrg rect->extent.width, rect->extent.height, 14127ec681f3Smrg true); 14137ec681f3Smrg } 14147ec681f3Smrg state->pctx->surface_destroy(state->pctx, clear_surf); 14157ec681f3Smrg} 14167ec681f3Smrg 14177ec681f3Smrgstatic struct lvp_image_view * 14187ec681f3Smrgget_attachment(struct rendering_state *state, 14197ec681f3Smrg unsigned idx) 14207ec681f3Smrg{ 14217ec681f3Smrg if (state->imageless_views) 14227ec681f3Smrg return state->imageless_views[idx]; 14237ec681f3Smrg else 14247ec681f3Smrg return state->vk_framebuffer->attachments[idx]; 14257ec681f3Smrg} 14267ec681f3Smrg 14277ec681f3Smrgstatic void render_subpass_clear(struct rendering_state *state) 14287ec681f3Smrg{ 14297ec681f3Smrg const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass]; 14307ec681f3Smrg 14317ec681f3Smrg for (unsigned i = 0; i < subpass->color_count; i++) { 14327ec681f3Smrg uint32_t a = subpass->color_attachments[i].attachment; 14337ec681f3Smrg 14347ec681f3Smrg if (!attachment_needs_clear(state, a)) 14357ec681f3Smrg continue; 14367ec681f3Smrg 14377ec681f3Smrg union pipe_color_union color_clear_val = { 0 }; 14387ec681f3Smrg const VkClearValue value = state->attachments[a].clear_value; 14397ec681f3Smrg color_clear_val.ui[0] = value.color.uint32[0]; 14407ec681f3Smrg color_clear_val.ui[1] = value.color.uint32[1]; 14417ec681f3Smrg color_clear_val.ui[2] = value.color.uint32[2]; 14427ec681f3Smrg color_clear_val.ui[3] = value.color.uint32[3]; 14437ec681f3Smrg 14447ec681f3Smrg struct lvp_image_view *imgv = get_attachment(state, a); 14457ec681f3Smrg 14467ec681f3Smrg assert(imgv->surface); 14477ec681f3Smrg 14487ec681f3Smrg if (subpass->view_mask) { 14497ec681f3Smrg u_foreach_bit(i, subpass->view_mask) 14507ec681f3Smrg clear_attachment_layers(state, imgv, &state->render_area, 14517ec681f3Smrg i, 1, 0, 0, 0, &color_clear_val); 14527ec681f3Smrg state->cleared_views[a] |= subpass->view_mask; 14537ec681f3Smrg } else { 14547ec681f3Smrg state->pctx->clear_render_target(state->pctx, 14557ec681f3Smrg imgv->surface, 14567ec681f3Smrg &color_clear_val, 14577ec681f3Smrg state->render_area.offset.x, state->render_area.offset.y, 14587ec681f3Smrg state->render_area.extent.width, state->render_area.extent.height, 14597ec681f3Smrg false); 14607ec681f3Smrg state->pending_clear_aspects[a] = 0; 14617ec681f3Smrg } 14627ec681f3Smrg } 14637ec681f3Smrg 14647ec681f3Smrg if (subpass->depth_stencil_attachment) { 14657ec681f3Smrg uint32_t ds = subpass->depth_stencil_attachment->attachment; 14667ec681f3Smrg 14677ec681f3Smrg if (!attachment_needs_clear(state, ds)) 14687ec681f3Smrg return; 14697ec681f3Smrg 14707ec681f3Smrg struct lvp_render_pass_attachment *att = &state->pass->attachments[ds]; 14717ec681f3Smrg struct lvp_image_view *imgv = get_attachment(state, ds); 14727ec681f3Smrg 14737ec681f3Smrg assert (util_format_is_depth_or_stencil(imgv->surface->format)); 14747ec681f3Smrg 14757ec681f3Smrg const struct util_format_description *desc = util_format_description(imgv->surface->format); 14767ec681f3Smrg double dclear_val = 0; 14777ec681f3Smrg uint32_t sclear_val = 0; 14787ec681f3Smrg uint32_t ds_clear_flags = 0; 14797ec681f3Smrg 14807ec681f3Smrg if ((util_format_has_stencil(desc) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) || 14817ec681f3Smrg (util_format_is_depth_and_stencil(imgv->surface->format) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)) { 14827ec681f3Smrg ds_clear_flags |= PIPE_CLEAR_STENCIL; 14837ec681f3Smrg if (att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) 14847ec681f3Smrg sclear_val = state->attachments[ds].clear_value.depthStencil.stencil; 14857ec681f3Smrg } 14867ec681f3Smrg if ((util_format_has_depth(desc) && att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) || 14877ec681f3Smrg (util_format_is_depth_and_stencil(imgv->surface->format) && att->load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)) { 14887ec681f3Smrg ds_clear_flags |= PIPE_CLEAR_DEPTH; 14897ec681f3Smrg if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) 14907ec681f3Smrg dclear_val = state->attachments[ds].clear_value.depthStencil.depth; 14917ec681f3Smrg } 14927ec681f3Smrg 14937ec681f3Smrg assert(imgv->surface); 14947ec681f3Smrg if (ds_clear_flags) { 14957ec681f3Smrg if (subpass->view_mask) { 14967ec681f3Smrg u_foreach_bit(i, subpass->view_mask) 14977ec681f3Smrg clear_attachment_layers(state, imgv, &state->render_area, 14987ec681f3Smrg i, 1, ds_clear_flags, dclear_val, sclear_val, NULL); 14997ec681f3Smrg state->cleared_views[ds] |= subpass->view_mask; 15007ec681f3Smrg } else { 15017ec681f3Smrg state->pctx->clear_depth_stencil(state->pctx, 15027ec681f3Smrg imgv->surface, 15037ec681f3Smrg ds_clear_flags, 15047ec681f3Smrg dclear_val, sclear_val, 15057ec681f3Smrg state->render_area.offset.x, state->render_area.offset.y, 15067ec681f3Smrg state->render_area.extent.width, state->render_area.extent.height, 15077ec681f3Smrg false); 15087ec681f3Smrg state->pending_clear_aspects[ds] = 0; 15097ec681f3Smrg } 15107ec681f3Smrg } 15117ec681f3Smrg 15127ec681f3Smrg } 15137ec681f3Smrg 15147ec681f3Smrg} 15157ec681f3Smrg 15167ec681f3Smrgstatic void render_subpass_clear_fast(struct rendering_state *state) 15177ec681f3Smrg{ 15187ec681f3Smrg /* attempt to use the clear interface first, then fallback to per-attchment clears */ 15197ec681f3Smrg const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass]; 15207ec681f3Smrg bool has_color_value = false; 15217ec681f3Smrg uint32_t buffers = 0; 15227ec681f3Smrg VkClearValue color_value = {0}; 15237ec681f3Smrg double dclear_val = 0; 15247ec681f3Smrg uint32_t sclear_val = 0; 15257ec681f3Smrg 15267ec681f3Smrg /* 15277ec681f3Smrg * the state tracker clear interface only works if all the attachments have the same 15287ec681f3Smrg * clear color. 15297ec681f3Smrg */ 15307ec681f3Smrg /* llvmpipe doesn't support scissored clears yet */ 15317ec681f3Smrg if (state->render_area.offset.x || state->render_area.offset.y) 15327ec681f3Smrg goto slow_clear; 15337ec681f3Smrg 15347ec681f3Smrg if (state->render_area.extent.width != state->framebuffer.width || 15357ec681f3Smrg state->render_area.extent.height != state->framebuffer.height) 15367ec681f3Smrg goto slow_clear; 15377ec681f3Smrg 15387ec681f3Smrg if (subpass->view_mask) 15397ec681f3Smrg goto slow_clear; 15407ec681f3Smrg for (unsigned i = 0; i < subpass->color_count; i++) { 15417ec681f3Smrg uint32_t a = subpass->color_attachments[i].attachment; 15427ec681f3Smrg 15437ec681f3Smrg if (!attachment_needs_clear(state, a)) 15447ec681f3Smrg continue; 15457ec681f3Smrg 15467ec681f3Smrg if (has_color_value) { 15477ec681f3Smrg if (memcmp(&color_value, &state->attachments[a].clear_value, sizeof(VkClearValue))) 15487ec681f3Smrg goto slow_clear; 15497ec681f3Smrg } else { 15507ec681f3Smrg memcpy(&color_value, &state->attachments[a].clear_value, sizeof(VkClearValue)); 15517ec681f3Smrg has_color_value = true; 15527ec681f3Smrg } 15537ec681f3Smrg } 15547ec681f3Smrg 15557ec681f3Smrg for (unsigned i = 0; i < subpass->color_count; i++) { 15567ec681f3Smrg uint32_t a = subpass->color_attachments[i].attachment; 15577ec681f3Smrg 15587ec681f3Smrg if (!attachment_needs_clear(state, a)) 15597ec681f3Smrg continue; 15607ec681f3Smrg buffers |= (PIPE_CLEAR_COLOR0 << i); 15617ec681f3Smrg state->pending_clear_aspects[a] = 0; 15627ec681f3Smrg } 15637ec681f3Smrg 15647ec681f3Smrg if (subpass->depth_stencil_attachment && 15657ec681f3Smrg attachment_needs_clear(state, subpass->depth_stencil_attachment->attachment)) { 15667ec681f3Smrg uint32_t ds = subpass->depth_stencil_attachment->attachment; 15677ec681f3Smrg 15687ec681f3Smrg struct lvp_render_pass_attachment *att = &state->pass->attachments[ds]; 15697ec681f3Smrg struct lvp_image_view *imgv = get_attachment(state, ds); 15707ec681f3Smrg const struct util_format_description *desc = util_format_description(imgv->surface->format); 15717ec681f3Smrg 15727ec681f3Smrg /* also clear stencil for don't care to avoid RMW */ 15737ec681f3Smrg if ((util_format_has_stencil(desc) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) || 15747ec681f3Smrg (util_format_is_depth_and_stencil(imgv->surface->format) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)) 15757ec681f3Smrg buffers |= PIPE_CLEAR_STENCIL; 15767ec681f3Smrg if (util_format_has_depth(desc) && att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) 15777ec681f3Smrg buffers |= PIPE_CLEAR_DEPTH; 15787ec681f3Smrg 15797ec681f3Smrg dclear_val = state->attachments[ds].clear_value.depthStencil.depth; 15807ec681f3Smrg sclear_val = state->attachments[ds].clear_value.depthStencil.stencil; 15817ec681f3Smrg state->pending_clear_aspects[ds] = 0; 15827ec681f3Smrg } 15837ec681f3Smrg 15847ec681f3Smrg union pipe_color_union col_val; 15857ec681f3Smrg for (unsigned i = 0; i < 4; i++) 15867ec681f3Smrg col_val.ui[i] = color_value.color.uint32[i]; 15877ec681f3Smrg 15887ec681f3Smrg state->pctx->clear(state->pctx, buffers, 15897ec681f3Smrg NULL, &col_val, 15907ec681f3Smrg dclear_val, sclear_val); 15917ec681f3Smrg return; 15927ec681f3Smrgslow_clear: 15937ec681f3Smrg render_subpass_clear(state); 15947ec681f3Smrg} 15957ec681f3Smrg 15967ec681f3Smrgstatic void render_pass_resolve(struct rendering_state *state) 15977ec681f3Smrg{ 15987ec681f3Smrg const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass]; 15997ec681f3Smrg 16007ec681f3Smrg if (subpass->depth_stencil_attachment && subpass->ds_resolve_attachment) { 16017ec681f3Smrg struct lvp_subpass_attachment src_att = *subpass->depth_stencil_attachment; 16027ec681f3Smrg struct lvp_subpass_attachment dst_att = *subpass->ds_resolve_attachment; 16037ec681f3Smrg if (dst_att.attachment != VK_ATTACHMENT_UNUSED) { 16047ec681f3Smrg int num_blits = 1; 16057ec681f3Smrg if (subpass->depth_resolve_mode != subpass->stencil_resolve_mode) 16067ec681f3Smrg num_blits = 2; 16077ec681f3Smrg 16087ec681f3Smrg for (unsigned i = 0; i < num_blits; i++) { 16097ec681f3Smrg 16107ec681f3Smrg if (i == 0 && subpass->depth_resolve_mode == VK_RESOLVE_MODE_NONE) 16117ec681f3Smrg continue; 16127ec681f3Smrg 16137ec681f3Smrg if (i == 1 && subpass->stencil_resolve_mode == VK_RESOLVE_MODE_NONE) 16147ec681f3Smrg continue; 16157ec681f3Smrg 16167ec681f3Smrg struct lvp_image_view *src_imgv = get_attachment(state, src_att.attachment); 16177ec681f3Smrg struct lvp_image_view *dst_imgv = get_attachment(state, dst_att.attachment); 16187ec681f3Smrg 16197ec681f3Smrg struct pipe_blit_info info; 16207ec681f3Smrg memset(&info, 0, sizeof(info)); 16217ec681f3Smrg 16227ec681f3Smrg info.src.resource = src_imgv->image->bo; 16237ec681f3Smrg info.dst.resource = dst_imgv->image->bo; 16247ec681f3Smrg info.src.format = src_imgv->pformat; 16257ec681f3Smrg info.dst.format = dst_imgv->pformat; 16267ec681f3Smrg info.filter = PIPE_TEX_FILTER_NEAREST; 16277ec681f3Smrg 16287ec681f3Smrg if (num_blits == 1) 16297ec681f3Smrg info.mask = PIPE_MASK_ZS; 16307ec681f3Smrg else if (i == 0) 16317ec681f3Smrg info.mask = PIPE_MASK_Z; 16327ec681f3Smrg else 16337ec681f3Smrg info.mask = PIPE_MASK_S; 16347ec681f3Smrg 16357ec681f3Smrg if (i == 0 && subpass->depth_resolve_mode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) 16367ec681f3Smrg info.sample0_only = true; 16377ec681f3Smrg if (i == 1 && subpass->stencil_resolve_mode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) 16387ec681f3Smrg info.sample0_only = true; 16397ec681f3Smrg 16407ec681f3Smrg info.src.box.x = state->render_area.offset.x; 16417ec681f3Smrg info.src.box.y = state->render_area.offset.y; 16427ec681f3Smrg info.src.box.width = state->render_area.extent.width; 16437ec681f3Smrg info.src.box.height = state->render_area.extent.height; 16447ec681f3Smrg info.src.box.depth = state->vk_framebuffer->layers; 16457ec681f3Smrg 16467ec681f3Smrg info.dst.box = info.src.box; 16477ec681f3Smrg 16487ec681f3Smrg state->pctx->blit(state->pctx, &info); 16497ec681f3Smrg } 16507ec681f3Smrg } 16517ec681f3Smrg } 16527ec681f3Smrg 16537ec681f3Smrg if (!subpass->has_color_resolve) 16547ec681f3Smrg return; 16557ec681f3Smrg for (uint32_t i = 0; i < subpass->color_count; i++) { 16567ec681f3Smrg struct lvp_subpass_attachment src_att = subpass->color_attachments[i]; 16577ec681f3Smrg struct lvp_subpass_attachment dst_att = subpass->resolve_attachments[i]; 16587ec681f3Smrg 16597ec681f3Smrg if (dst_att.attachment == VK_ATTACHMENT_UNUSED) 16607ec681f3Smrg continue; 16617ec681f3Smrg 16627ec681f3Smrg struct lvp_image_view *src_imgv = get_attachment(state, src_att.attachment); 16637ec681f3Smrg struct lvp_image_view *dst_imgv = get_attachment(state, dst_att.attachment); 16647ec681f3Smrg 16657ec681f3Smrg struct pipe_blit_info info; 16667ec681f3Smrg memset(&info, 0, sizeof(info)); 16677ec681f3Smrg 16687ec681f3Smrg info.src.resource = src_imgv->image->bo; 16697ec681f3Smrg info.dst.resource = dst_imgv->image->bo; 16707ec681f3Smrg info.src.format = src_imgv->pformat; 16717ec681f3Smrg info.dst.format = dst_imgv->pformat; 16727ec681f3Smrg info.filter = PIPE_TEX_FILTER_NEAREST; 16737ec681f3Smrg info.mask = PIPE_MASK_RGBA; 16747ec681f3Smrg info.src.box.x = state->render_area.offset.x; 16757ec681f3Smrg info.src.box.y = state->render_area.offset.y; 16767ec681f3Smrg info.src.box.width = state->render_area.extent.width; 16777ec681f3Smrg info.src.box.height = state->render_area.extent.height; 16787ec681f3Smrg info.src.box.depth = state->vk_framebuffer->layers; 16797ec681f3Smrg 16807ec681f3Smrg info.dst.box = info.src.box; 16817ec681f3Smrg 16827ec681f3Smrg info.src.level = src_imgv->subresourceRange.baseMipLevel; 16837ec681f3Smrg info.dst.level = dst_imgv->subresourceRange.baseMipLevel; 16847ec681f3Smrg 16857ec681f3Smrg state->pctx->blit(state->pctx, &info); 16867ec681f3Smrg } 16877ec681f3Smrg} 16887ec681f3Smrg 16897ec681f3Smrgstatic void begin_render_subpass(struct rendering_state *state, 16907ec681f3Smrg int subpass_idx) 16917ec681f3Smrg{ 16927ec681f3Smrg state->subpass = subpass_idx; 16937ec681f3Smrg 16947ec681f3Smrg state->framebuffer.nr_cbufs = 0; 16957ec681f3Smrg 16967ec681f3Smrg const struct lvp_subpass *subpass = &state->pass->subpasses[subpass_idx]; 16977ec681f3Smrg for (unsigned i = 0; i < subpass->color_count; i++) { 16987ec681f3Smrg struct lvp_subpass_attachment *color_att = &subpass->color_attachments[i]; 16997ec681f3Smrg if (color_att->attachment != VK_ATTACHMENT_UNUSED) { 17007ec681f3Smrg struct lvp_image_view *imgv = get_attachment(state, color_att->attachment); 17017ec681f3Smrg add_img_view_surface(state, imgv, state->pass->attachments[color_att->attachment].format, state->framebuffer.width, state->framebuffer.height); 17027ec681f3Smrg state->framebuffer.cbufs[state->framebuffer.nr_cbufs] = imgv->surface; 17037ec681f3Smrg } else 17047ec681f3Smrg state->framebuffer.cbufs[state->framebuffer.nr_cbufs] = NULL; 17057ec681f3Smrg state->framebuffer.nr_cbufs++; 17067ec681f3Smrg } 17077ec681f3Smrg 17087ec681f3Smrg if (subpass->depth_stencil_attachment) { 17097ec681f3Smrg struct lvp_subpass_attachment *ds_att = subpass->depth_stencil_attachment; 17107ec681f3Smrg 17117ec681f3Smrg if (ds_att->attachment != VK_ATTACHMENT_UNUSED) { 17127ec681f3Smrg struct lvp_image_view *imgv = get_attachment(state, ds_att->attachment); 17137ec681f3Smrg add_img_view_surface(state, imgv, state->pass->attachments[ds_att->attachment].format, state->framebuffer.width, state->framebuffer.height); 17147ec681f3Smrg state->framebuffer.zsbuf = imgv->surface; 17157ec681f3Smrg } 17167ec681f3Smrg } 17177ec681f3Smrg 17187ec681f3Smrg state->pctx->set_framebuffer_state(state->pctx, 17197ec681f3Smrg &state->framebuffer); 17207ec681f3Smrg 17217ec681f3Smrg if (subpass_needs_clear(state)) 17227ec681f3Smrg render_subpass_clear_fast(state); 17237ec681f3Smrg} 17247ec681f3Smrg 17257ec681f3Smrgstatic void begin_render_pass(const VkRenderPassBeginInfo *render_pass_begin, 17267ec681f3Smrg struct rendering_state *state) 17277ec681f3Smrg{ 17287ec681f3Smrg LVP_FROM_HANDLE(lvp_render_pass, pass, render_pass_begin->renderPass); 17297ec681f3Smrg LVP_FROM_HANDLE(lvp_framebuffer, framebuffer, render_pass_begin->framebuffer); 17307ec681f3Smrg const struct VkRenderPassAttachmentBeginInfo *attachment_info = 17317ec681f3Smrg vk_find_struct_const(render_pass_begin->pNext, 17327ec681f3Smrg RENDER_PASS_ATTACHMENT_BEGIN_INFO); 17337ec681f3Smrg 17347ec681f3Smrg state->pass = pass; 17357ec681f3Smrg state->vk_framebuffer = framebuffer; 17367ec681f3Smrg state->render_area = render_pass_begin->renderArea; 17377ec681f3Smrg 17387ec681f3Smrg if (attachment_info) { 17397ec681f3Smrg state->imageless_views = realloc(state->imageless_views, sizeof(*state->imageless_views) * attachment_info->attachmentCount); 17407ec681f3Smrg for (unsigned i = 0; i < attachment_info->attachmentCount; i++) 17417ec681f3Smrg state->imageless_views[i] = lvp_image_view_from_handle(attachment_info->pAttachments[i]); 17427ec681f3Smrg } 17437ec681f3Smrg 17447ec681f3Smrg state->framebuffer.width = state->vk_framebuffer->width; 17457ec681f3Smrg state->framebuffer.height = state->vk_framebuffer->height; 17467ec681f3Smrg state->framebuffer.layers = state->vk_framebuffer->layers; 17477ec681f3Smrg 17487ec681f3Smrg if (state->num_pending_aspects < state->pass->attachment_count) { 17497ec681f3Smrg state->pending_clear_aspects = realloc(state->pending_clear_aspects, sizeof(VkImageAspectFlags) * state->pass->attachment_count); 17507ec681f3Smrg state->cleared_views = realloc(state->cleared_views, sizeof(uint32_t) * state->pass->attachment_count); 17517ec681f3Smrg state->num_pending_aspects = state->pass->attachment_count; 17527ec681f3Smrg } 17537ec681f3Smrg 17547ec681f3Smrg state->attachments = realloc(state->attachments, sizeof(*state->attachments) * pass->attachment_count); 17557ec681f3Smrg for (unsigned i = 0; i < state->pass->attachment_count; i++) { 17567ec681f3Smrg struct lvp_render_pass_attachment *att = &pass->attachments[i]; 17577ec681f3Smrg VkImageAspectFlags att_aspects = vk_format_aspects(att->format); 17587ec681f3Smrg VkImageAspectFlags clear_aspects = 0; 17597ec681f3Smrg if (att_aspects == VK_IMAGE_ASPECT_COLOR_BIT) { 17607ec681f3Smrg /* color attachment */ 17617ec681f3Smrg if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) { 17627ec681f3Smrg clear_aspects |= VK_IMAGE_ASPECT_COLOR_BIT; 17637ec681f3Smrg } 17647ec681f3Smrg } else { 17657ec681f3Smrg /* depthstencil attachment */ 17667ec681f3Smrg if ((att_aspects & VK_IMAGE_ASPECT_DEPTH_BIT) && 17677ec681f3Smrg att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) { 17687ec681f3Smrg clear_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT; 17697ec681f3Smrg if ((att_aspects & VK_IMAGE_ASPECT_STENCIL_BIT) && 17707ec681f3Smrg att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE) 17717ec681f3Smrg clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT; 17727ec681f3Smrg } 17737ec681f3Smrg if ((att_aspects & VK_IMAGE_ASPECT_STENCIL_BIT) && 17747ec681f3Smrg att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) { 17757ec681f3Smrg clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT; 17767ec681f3Smrg } 17777ec681f3Smrg } 17787ec681f3Smrg state->attachments[i].pending_clear_aspects = clear_aspects; 17797ec681f3Smrg if (clear_aspects) 17807ec681f3Smrg state->attachments[i].clear_value = render_pass_begin->pClearValues[i]; 17817ec681f3Smrg 17827ec681f3Smrg state->pending_clear_aspects[i] = state->attachments[i].pending_clear_aspects; 17837ec681f3Smrg state->cleared_views[i] = 0; 17847ec681f3Smrg } 17857ec681f3Smrg begin_render_subpass(state, 0); 17867ec681f3Smrg} 17877ec681f3Smrg 17887ec681f3Smrg 17897ec681f3Smrgstatic void handle_begin_render_pass(struct vk_cmd_queue_entry *cmd, 17907ec681f3Smrg struct rendering_state *state) 17917ec681f3Smrg{ 17927ec681f3Smrg begin_render_pass(cmd->u.begin_render_pass.render_pass_begin, state); 17937ec681f3Smrg} 17947ec681f3Smrg 17957ec681f3Smrgstatic void handle_begin_render_pass2(struct vk_cmd_queue_entry *cmd, 17967ec681f3Smrg struct rendering_state *state) 17977ec681f3Smrg{ 17987ec681f3Smrg begin_render_pass(cmd->u.begin_render_pass2.render_pass_begin, state); 17997ec681f3Smrg} 18007ec681f3Smrg 18017ec681f3Smrgstatic void handle_end_render_pass2(struct vk_cmd_queue_entry *cmd, 18027ec681f3Smrg struct rendering_state *state) 18037ec681f3Smrg{ 18047ec681f3Smrg state->pctx->flush(state->pctx, NULL, 0); 18057ec681f3Smrg 18067ec681f3Smrg render_pass_resolve(state); 18077ec681f3Smrg 18087ec681f3Smrg free(state->attachments); 18097ec681f3Smrg state->attachments = NULL; 18107ec681f3Smrg state->pass = NULL; 18117ec681f3Smrg state->subpass = 0; 18127ec681f3Smrg} 18137ec681f3Smrg 18147ec681f3Smrgstatic void handle_next_subpass2(struct vk_cmd_queue_entry *cmd, 18157ec681f3Smrg struct rendering_state *state) 18167ec681f3Smrg{ 18177ec681f3Smrg state->pctx->flush(state->pctx, NULL, 0); 18187ec681f3Smrg render_pass_resolve(state); 18197ec681f3Smrg state->subpass++; 18207ec681f3Smrg begin_render_subpass(state, state->subpass); 18217ec681f3Smrg} 18227ec681f3Smrg 18237ec681f3Smrgstatic void handle_draw(struct vk_cmd_queue_entry *cmd, 18247ec681f3Smrg struct rendering_state *state) 18257ec681f3Smrg{ 18267ec681f3Smrg const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass]; 18277ec681f3Smrg struct pipe_draw_start_count_bias draw; 18287ec681f3Smrg 18297ec681f3Smrg state->info.index_size = 0; 18307ec681f3Smrg state->info.index.resource = NULL; 18317ec681f3Smrg state->info.start_instance = cmd->u.draw.first_instance; 18327ec681f3Smrg state->info.instance_count = cmd->u.draw.instance_count; 18337ec681f3Smrg state->info.view_mask = subpass->view_mask; 18347ec681f3Smrg 18357ec681f3Smrg draw.start = cmd->u.draw.first_vertex; 18367ec681f3Smrg draw.count = cmd->u.draw.vertex_count; 18377ec681f3Smrg 18387ec681f3Smrg state->pctx->set_patch_vertices(state->pctx, state->patch_vertices); 18397ec681f3Smrg state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, &draw, 1); 18407ec681f3Smrg} 18417ec681f3Smrg 18427ec681f3Smrgstatic void handle_draw_multi(struct vk_cmd_queue_entry *cmd, 18437ec681f3Smrg struct rendering_state *state) 18447ec681f3Smrg{ 18457ec681f3Smrg const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass]; 18467ec681f3Smrg struct pipe_draw_start_count_bias *draws = calloc(cmd->u.draw_multi_ext.draw_count, 18477ec681f3Smrg sizeof(*draws)); 18487ec681f3Smrg 18497ec681f3Smrg state->info.index_size = 0; 18507ec681f3Smrg state->info.index.resource = NULL; 18517ec681f3Smrg state->info.start_instance = cmd->u.draw_multi_ext.first_instance; 18527ec681f3Smrg state->info.instance_count = cmd->u.draw_multi_ext.instance_count; 18537ec681f3Smrg state->info.view_mask = subpass->view_mask; 18547ec681f3Smrg if (cmd->u.draw_multi_ext.draw_count > 1) 18557ec681f3Smrg state->info.increment_draw_id = true; 18567ec681f3Smrg 18577ec681f3Smrg for(unsigned i = 0; i < cmd->u.draw_multi_ext.draw_count; i++) { 18587ec681f3Smrg draws[i].start = cmd->u.draw_multi_ext.vertex_info[i].firstVertex; 18597ec681f3Smrg draws[i].count = cmd->u.draw_multi_ext.vertex_info[i].vertexCount; 18607ec681f3Smrg draws[i].index_bias = 0; 18617ec681f3Smrg } 18627ec681f3Smrg 18637ec681f3Smrg state->pctx->set_patch_vertices(state->pctx, state->patch_vertices); 18647ec681f3Smrg 18657ec681f3Smrg if (cmd->u.draw_multi_indexed_ext.draw_count) 18667ec681f3Smrg state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, draws, cmd->u.draw_multi_ext.draw_count); 18677ec681f3Smrg 18687ec681f3Smrg free(draws); 18697ec681f3Smrg} 18707ec681f3Smrg 18717ec681f3Smrgstatic void set_viewport(unsigned first_viewport, unsigned viewport_count, 18727ec681f3Smrg const VkViewport* viewports, 18737ec681f3Smrg struct rendering_state *state) 18747ec681f3Smrg{ 18757ec681f3Smrg int i; 18767ec681f3Smrg unsigned base = 0; 18777ec681f3Smrg if (first_viewport == UINT32_MAX) 18787ec681f3Smrg state->num_viewports = viewport_count; 18797ec681f3Smrg else 18807ec681f3Smrg base = first_viewport; 18817ec681f3Smrg 18827ec681f3Smrg for (i = 0; i < viewport_count; i++) { 18837ec681f3Smrg int idx = i + base; 18847ec681f3Smrg const VkViewport *vp = &viewports[i]; 18857ec681f3Smrg get_viewport_xform(vp, state->viewports[idx].scale, state->viewports[idx].translate); 18867ec681f3Smrg } 18877ec681f3Smrg state->vp_dirty = true; 18887ec681f3Smrg} 18897ec681f3Smrg 18907ec681f3Smrgstatic void handle_set_viewport(struct vk_cmd_queue_entry *cmd, 18917ec681f3Smrg struct rendering_state *state) 18927ec681f3Smrg{ 18937ec681f3Smrg set_viewport(cmd->u.set_viewport.first_viewport, 18947ec681f3Smrg cmd->u.set_viewport.viewport_count, 18957ec681f3Smrg cmd->u.set_viewport.viewports, 18967ec681f3Smrg state); 18977ec681f3Smrg} 18987ec681f3Smrg 18997ec681f3Smrgstatic void handle_set_viewport_with_count(struct vk_cmd_queue_entry *cmd, 19007ec681f3Smrg struct rendering_state *state) 19017ec681f3Smrg{ 19027ec681f3Smrg set_viewport(UINT32_MAX, 19037ec681f3Smrg cmd->u.set_viewport_with_count_ext.viewport_count, 19047ec681f3Smrg cmd->u.set_viewport_with_count_ext.viewports, 19057ec681f3Smrg state); 19067ec681f3Smrg} 19077ec681f3Smrg 19087ec681f3Smrgstatic void set_scissor(unsigned first_scissor, 19097ec681f3Smrg unsigned scissor_count, 19107ec681f3Smrg const VkRect2D *scissors, 19117ec681f3Smrg struct rendering_state *state) 19127ec681f3Smrg{ 19137ec681f3Smrg int i; 19147ec681f3Smrg unsigned base = 0; 19157ec681f3Smrg if (first_scissor == UINT32_MAX) 19167ec681f3Smrg state->num_scissors = scissor_count; 19177ec681f3Smrg else 19187ec681f3Smrg base = first_scissor; 19197ec681f3Smrg 19207ec681f3Smrg for (i = 0; i < scissor_count; i++) { 19217ec681f3Smrg int idx = i + base; 19227ec681f3Smrg const VkRect2D *ss = &scissors[i]; 19237ec681f3Smrg state->scissors[idx].minx = ss->offset.x; 19247ec681f3Smrg state->scissors[idx].miny = ss->offset.y; 19257ec681f3Smrg state->scissors[idx].maxx = ss->offset.x + ss->extent.width; 19267ec681f3Smrg state->scissors[idx].maxy = ss->offset.y + ss->extent.height; 19277ec681f3Smrg } 19287ec681f3Smrg state->scissor_dirty = true; 19297ec681f3Smrg} 19307ec681f3Smrg 19317ec681f3Smrgstatic void handle_set_scissor(struct vk_cmd_queue_entry *cmd, 19327ec681f3Smrg struct rendering_state *state) 19337ec681f3Smrg{ 19347ec681f3Smrg set_scissor(cmd->u.set_scissor.first_scissor, 19357ec681f3Smrg cmd->u.set_scissor.scissor_count, 19367ec681f3Smrg cmd->u.set_scissor.scissors, 19377ec681f3Smrg state); 19387ec681f3Smrg} 19397ec681f3Smrg 19407ec681f3Smrgstatic void handle_set_scissor_with_count(struct vk_cmd_queue_entry *cmd, 19417ec681f3Smrg struct rendering_state *state) 19427ec681f3Smrg{ 19437ec681f3Smrg set_scissor(UINT32_MAX, 19447ec681f3Smrg cmd->u.set_scissor_with_count_ext.scissor_count, 19457ec681f3Smrg cmd->u.set_scissor_with_count_ext.scissors, 19467ec681f3Smrg state); 19477ec681f3Smrg} 19487ec681f3Smrg 19497ec681f3Smrgstatic void handle_set_line_width(struct vk_cmd_queue_entry *cmd, 19507ec681f3Smrg struct rendering_state *state) 19517ec681f3Smrg{ 19527ec681f3Smrg state->rs_state.line_width = cmd->u.set_line_width.line_width; 19537ec681f3Smrg state->rs_dirty = true; 19547ec681f3Smrg} 19557ec681f3Smrg 19567ec681f3Smrgstatic void handle_set_depth_bias(struct vk_cmd_queue_entry *cmd, 19577ec681f3Smrg struct rendering_state *state) 19587ec681f3Smrg{ 19597ec681f3Smrg state->depth_bias.offset_units = cmd->u.set_depth_bias.depth_bias_constant_factor; 19607ec681f3Smrg state->depth_bias.offset_scale = cmd->u.set_depth_bias.depth_bias_slope_factor; 19617ec681f3Smrg state->depth_bias.offset_clamp = cmd->u.set_depth_bias.depth_bias_clamp; 19627ec681f3Smrg state->rs_dirty = true; 19637ec681f3Smrg} 19647ec681f3Smrg 19657ec681f3Smrgstatic void handle_set_blend_constants(struct vk_cmd_queue_entry *cmd, 19667ec681f3Smrg struct rendering_state *state) 19677ec681f3Smrg{ 19687ec681f3Smrg memcpy(state->blend_color.color, cmd->u.set_blend_constants.blend_constants, 4 * sizeof(float)); 19697ec681f3Smrg state->blend_color_dirty = true; 19707ec681f3Smrg} 19717ec681f3Smrg 19727ec681f3Smrgstatic void handle_set_depth_bounds(struct vk_cmd_queue_entry *cmd, 19737ec681f3Smrg struct rendering_state *state) 19747ec681f3Smrg{ 19757ec681f3Smrg state->dsa_dirty |= !DOUBLE_EQ(state->dsa_state.depth_bounds_min, cmd->u.set_depth_bounds.min_depth_bounds); 19767ec681f3Smrg state->dsa_dirty |= !DOUBLE_EQ(state->dsa_state.depth_bounds_max, cmd->u.set_depth_bounds.max_depth_bounds); 19777ec681f3Smrg state->dsa_state.depth_bounds_min = cmd->u.set_depth_bounds.min_depth_bounds; 19787ec681f3Smrg state->dsa_state.depth_bounds_max = cmd->u.set_depth_bounds.max_depth_bounds; 19797ec681f3Smrg} 19807ec681f3Smrg 19817ec681f3Smrgstatic void handle_set_stencil_compare_mask(struct vk_cmd_queue_entry *cmd, 19827ec681f3Smrg struct rendering_state *state) 19837ec681f3Smrg{ 19847ec681f3Smrg if (cmd->u.set_stencil_compare_mask.face_mask & VK_STENCIL_FACE_FRONT_BIT) 19857ec681f3Smrg state->dsa_state.stencil[0].valuemask = cmd->u.set_stencil_compare_mask.compare_mask; 19867ec681f3Smrg if (cmd->u.set_stencil_compare_mask.face_mask & VK_STENCIL_FACE_BACK_BIT) 19877ec681f3Smrg state->dsa_state.stencil[1].valuemask = cmd->u.set_stencil_compare_mask.compare_mask; 19887ec681f3Smrg state->dsa_dirty = true; 19897ec681f3Smrg} 19907ec681f3Smrg 19917ec681f3Smrgstatic void handle_set_stencil_write_mask(struct vk_cmd_queue_entry *cmd, 19927ec681f3Smrg struct rendering_state *state) 19937ec681f3Smrg{ 19947ec681f3Smrg if (cmd->u.set_stencil_write_mask.face_mask & VK_STENCIL_FACE_FRONT_BIT) 19957ec681f3Smrg state->dsa_state.stencil[0].writemask = cmd->u.set_stencil_write_mask.write_mask; 19967ec681f3Smrg if (cmd->u.set_stencil_write_mask.face_mask & VK_STENCIL_FACE_BACK_BIT) 19977ec681f3Smrg state->dsa_state.stencil[1].writemask = cmd->u.set_stencil_write_mask.write_mask; 19987ec681f3Smrg state->dsa_dirty = true; 19997ec681f3Smrg} 20007ec681f3Smrg 20017ec681f3Smrgstatic void handle_set_stencil_reference(struct vk_cmd_queue_entry *cmd, 20027ec681f3Smrg struct rendering_state *state) 20037ec681f3Smrg{ 20047ec681f3Smrg if (cmd->u.set_stencil_reference.face_mask & VK_STENCIL_FACE_FRONT_BIT) 20057ec681f3Smrg state->stencil_ref.ref_value[0] = cmd->u.set_stencil_reference.reference; 20067ec681f3Smrg if (cmd->u.set_stencil_reference.face_mask & VK_STENCIL_FACE_BACK_BIT) 20077ec681f3Smrg state->stencil_ref.ref_value[1] = cmd->u.set_stencil_reference.reference; 20087ec681f3Smrg state->stencil_ref_dirty = true; 20097ec681f3Smrg} 20107ec681f3Smrg 20117ec681f3Smrgstatic void 20127ec681f3Smrgcopy_depth_rect(ubyte * dst, 20137ec681f3Smrg enum pipe_format dst_format, 20147ec681f3Smrg unsigned dst_stride, 20157ec681f3Smrg unsigned dst_x, 20167ec681f3Smrg unsigned dst_y, 20177ec681f3Smrg unsigned width, 20187ec681f3Smrg unsigned height, 20197ec681f3Smrg const ubyte * src, 20207ec681f3Smrg enum pipe_format src_format, 20217ec681f3Smrg int src_stride, 20227ec681f3Smrg unsigned src_x, 20237ec681f3Smrg unsigned src_y) 20247ec681f3Smrg{ 20257ec681f3Smrg int src_stride_pos = src_stride < 0 ? -src_stride : src_stride; 20267ec681f3Smrg int src_blocksize = util_format_get_blocksize(src_format); 20277ec681f3Smrg int src_blockwidth = util_format_get_blockwidth(src_format); 20287ec681f3Smrg int src_blockheight = util_format_get_blockheight(src_format); 20297ec681f3Smrg int dst_blocksize = util_format_get_blocksize(dst_format); 20307ec681f3Smrg int dst_blockwidth = util_format_get_blockwidth(dst_format); 20317ec681f3Smrg int dst_blockheight = util_format_get_blockheight(dst_format); 20327ec681f3Smrg 20337ec681f3Smrg assert(src_blocksize > 0); 20347ec681f3Smrg assert(src_blockwidth > 0); 20357ec681f3Smrg assert(src_blockheight > 0); 20367ec681f3Smrg 20377ec681f3Smrg dst_x /= dst_blockwidth; 20387ec681f3Smrg dst_y /= dst_blockheight; 20397ec681f3Smrg width = (width + src_blockwidth - 1)/src_blockwidth; 20407ec681f3Smrg height = (height + src_blockheight - 1)/src_blockheight; 20417ec681f3Smrg src_x /= src_blockwidth; 20427ec681f3Smrg src_y /= src_blockheight; 20437ec681f3Smrg 20447ec681f3Smrg dst += dst_x * dst_blocksize; 20457ec681f3Smrg src += src_x * src_blocksize; 20467ec681f3Smrg dst += dst_y * dst_stride; 20477ec681f3Smrg src += src_y * src_stride_pos; 20487ec681f3Smrg 20497ec681f3Smrg if (dst_format == PIPE_FORMAT_S8_UINT) { 20507ec681f3Smrg if (src_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) { 20517ec681f3Smrg util_format_z32_float_s8x24_uint_unpack_s_8uint(dst, dst_stride, 20527ec681f3Smrg src, src_stride, 20537ec681f3Smrg width, height); 20547ec681f3Smrg } else if (src_format == PIPE_FORMAT_Z24_UNORM_S8_UINT) { 20557ec681f3Smrg util_format_z24_unorm_s8_uint_unpack_s_8uint(dst, dst_stride, 20567ec681f3Smrg src, src_stride, 20577ec681f3Smrg width, height); 20587ec681f3Smrg } else { 20597ec681f3Smrg } 20607ec681f3Smrg } else if (dst_format == PIPE_FORMAT_Z24X8_UNORM) { 20617ec681f3Smrg util_format_z24_unorm_s8_uint_unpack_z24(dst, dst_stride, 20627ec681f3Smrg src, src_stride, 20637ec681f3Smrg width, height); 20647ec681f3Smrg } else if (dst_format == PIPE_FORMAT_Z32_FLOAT) { 20657ec681f3Smrg if (src_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) { 20667ec681f3Smrg util_format_z32_float_s8x24_uint_unpack_z_float((float *)dst, dst_stride, 20677ec681f3Smrg src, src_stride, 20687ec681f3Smrg width, height); 20697ec681f3Smrg } 20707ec681f3Smrg } else if (dst_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) { 20717ec681f3Smrg if (src_format == PIPE_FORMAT_Z32_FLOAT) 20727ec681f3Smrg util_format_z32_float_s8x24_uint_pack_z_float(dst, dst_stride, 20737ec681f3Smrg (float *)src, src_stride, 20747ec681f3Smrg width, height); 20757ec681f3Smrg else if (src_format == PIPE_FORMAT_S8_UINT) 20767ec681f3Smrg util_format_z32_float_s8x24_uint_pack_s_8uint(dst, dst_stride, 20777ec681f3Smrg src, src_stride, 20787ec681f3Smrg width, height); 20797ec681f3Smrg } else if (dst_format == PIPE_FORMAT_Z24_UNORM_S8_UINT) { 20807ec681f3Smrg if (src_format == PIPE_FORMAT_S8_UINT) 20817ec681f3Smrg util_format_z24_unorm_s8_uint_pack_s_8uint(dst, dst_stride, 20827ec681f3Smrg src, src_stride, 20837ec681f3Smrg width, height); 20847ec681f3Smrg if (src_format == PIPE_FORMAT_Z24X8_UNORM) 20857ec681f3Smrg util_format_z24_unorm_s8_uint_pack_z24(dst, dst_stride, 20867ec681f3Smrg src, src_stride, 20877ec681f3Smrg width, height); 20887ec681f3Smrg } 20897ec681f3Smrg} 20907ec681f3Smrg 20917ec681f3Smrgstatic void 20927ec681f3Smrgcopy_depth_box(ubyte *dst, 20937ec681f3Smrg enum pipe_format dst_format, 20947ec681f3Smrg unsigned dst_stride, unsigned dst_slice_stride, 20957ec681f3Smrg unsigned dst_x, unsigned dst_y, unsigned dst_z, 20967ec681f3Smrg unsigned width, unsigned height, unsigned depth, 20977ec681f3Smrg const ubyte * src, 20987ec681f3Smrg enum pipe_format src_format, 20997ec681f3Smrg int src_stride, unsigned src_slice_stride, 21007ec681f3Smrg unsigned src_x, unsigned src_y, unsigned src_z) 21017ec681f3Smrg{ 21027ec681f3Smrg unsigned z; 21037ec681f3Smrg dst += dst_z * dst_slice_stride; 21047ec681f3Smrg src += src_z * src_slice_stride; 21057ec681f3Smrg for (z = 0; z < depth; ++z) { 21067ec681f3Smrg copy_depth_rect(dst, 21077ec681f3Smrg dst_format, 21087ec681f3Smrg dst_stride, 21097ec681f3Smrg dst_x, dst_y, 21107ec681f3Smrg width, height, 21117ec681f3Smrg src, 21127ec681f3Smrg src_format, 21137ec681f3Smrg src_stride, 21147ec681f3Smrg src_x, src_y); 21157ec681f3Smrg 21167ec681f3Smrg dst += dst_slice_stride; 21177ec681f3Smrg src += src_slice_stride; 21187ec681f3Smrg } 21197ec681f3Smrg} 21207ec681f3Smrg 21217ec681f3Smrgstatic void handle_copy_image_to_buffer2_khr(struct vk_cmd_queue_entry *cmd, 21227ec681f3Smrg struct rendering_state *state) 21237ec681f3Smrg{ 21247ec681f3Smrg int i; 21257ec681f3Smrg struct VkCopyImageToBufferInfo2KHR *copycmd = cmd->u.copy_image_to_buffer2_khr.copy_image_to_buffer_info; 21267ec681f3Smrg LVP_FROM_HANDLE(lvp_image, src_image, copycmd->srcImage); 21277ec681f3Smrg struct pipe_box box, dbox; 21287ec681f3Smrg struct pipe_transfer *src_t, *dst_t; 21297ec681f3Smrg ubyte *src_data, *dst_data; 21307ec681f3Smrg 21317ec681f3Smrg state->pctx->flush(state->pctx, NULL, 0); 21327ec681f3Smrg 21337ec681f3Smrg for (i = 0; i < copycmd->regionCount; i++) { 21347ec681f3Smrg 21357ec681f3Smrg box.x = copycmd->pRegions[i].imageOffset.x; 21367ec681f3Smrg box.y = copycmd->pRegions[i].imageOffset.y; 21377ec681f3Smrg box.z = src_image->vk.image_type == VK_IMAGE_TYPE_3D ? copycmd->pRegions[i].imageOffset.z : copycmd->pRegions[i].imageSubresource.baseArrayLayer; 21387ec681f3Smrg box.width = copycmd->pRegions[i].imageExtent.width; 21397ec681f3Smrg box.height = copycmd->pRegions[i].imageExtent.height; 21407ec681f3Smrg box.depth = src_image->vk.image_type == VK_IMAGE_TYPE_3D ? copycmd->pRegions[i].imageExtent.depth : copycmd->pRegions[i].imageSubresource.layerCount; 21417ec681f3Smrg 21427ec681f3Smrg src_data = state->pctx->texture_map(state->pctx, 21437ec681f3Smrg src_image->bo, 21447ec681f3Smrg copycmd->pRegions[i].imageSubresource.mipLevel, 21457ec681f3Smrg PIPE_MAP_READ, 21467ec681f3Smrg &box, 21477ec681f3Smrg &src_t); 21487ec681f3Smrg 21497ec681f3Smrg dbox.x = copycmd->pRegions[i].bufferOffset; 21507ec681f3Smrg dbox.y = 0; 21517ec681f3Smrg dbox.z = 0; 21527ec681f3Smrg dbox.width = lvp_buffer_from_handle(copycmd->dstBuffer)->bo->width0; 21537ec681f3Smrg dbox.height = 1; 21547ec681f3Smrg dbox.depth = 1; 21557ec681f3Smrg dst_data = state->pctx->buffer_map(state->pctx, 21567ec681f3Smrg lvp_buffer_from_handle(copycmd->dstBuffer)->bo, 21577ec681f3Smrg 0, 21587ec681f3Smrg PIPE_MAP_WRITE, 21597ec681f3Smrg &dbox, 21607ec681f3Smrg &dst_t); 21617ec681f3Smrg 21627ec681f3Smrg enum pipe_format src_format = src_image->bo->format; 21637ec681f3Smrg enum pipe_format dst_format = src_format; 21647ec681f3Smrg if (util_format_is_depth_or_stencil(src_format)) { 21657ec681f3Smrg if (copycmd->pRegions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) { 21667ec681f3Smrg dst_format = util_format_get_depth_only(src_format); 21677ec681f3Smrg } else if (copycmd->pRegions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) { 21687ec681f3Smrg dst_format = PIPE_FORMAT_S8_UINT; 21697ec681f3Smrg } 21707ec681f3Smrg } 21717ec681f3Smrg 21727ec681f3Smrg unsigned buffer_row_len = util_format_get_stride(dst_format, copycmd->pRegions[i].bufferRowLength); 21737ec681f3Smrg if (buffer_row_len == 0) 21747ec681f3Smrg buffer_row_len = util_format_get_stride(dst_format, copycmd->pRegions[i].imageExtent.width); 21757ec681f3Smrg unsigned buffer_image_height = copycmd->pRegions[i].bufferImageHeight; 21767ec681f3Smrg if (buffer_image_height == 0) 21777ec681f3Smrg buffer_image_height = copycmd->pRegions[i].imageExtent.height; 21787ec681f3Smrg 21797ec681f3Smrg unsigned img_stride = util_format_get_2d_size(dst_format, buffer_row_len, buffer_image_height); 21807ec681f3Smrg if (src_format != dst_format) { 21817ec681f3Smrg copy_depth_box(dst_data, dst_format, 21827ec681f3Smrg buffer_row_len, img_stride, 21837ec681f3Smrg 0, 0, 0, 21847ec681f3Smrg copycmd->pRegions[i].imageExtent.width, 21857ec681f3Smrg copycmd->pRegions[i].imageExtent.height, 21867ec681f3Smrg box.depth, 21877ec681f3Smrg src_data, src_format, src_t->stride, src_t->layer_stride, 0, 0, 0); 21887ec681f3Smrg } else { 21897ec681f3Smrg util_copy_box((ubyte *)dst_data, src_format, 21907ec681f3Smrg buffer_row_len, img_stride, 21917ec681f3Smrg 0, 0, 0, 21927ec681f3Smrg copycmd->pRegions[i].imageExtent.width, 21937ec681f3Smrg copycmd->pRegions[i].imageExtent.height, 21947ec681f3Smrg box.depth, 21957ec681f3Smrg src_data, src_t->stride, src_t->layer_stride, 0, 0, 0); 21967ec681f3Smrg } 21977ec681f3Smrg state->pctx->texture_unmap(state->pctx, src_t); 21987ec681f3Smrg state->pctx->buffer_unmap(state->pctx, dst_t); 21997ec681f3Smrg } 22007ec681f3Smrg} 22017ec681f3Smrg 22027ec681f3Smrgstatic void handle_copy_buffer_to_image(struct vk_cmd_queue_entry *cmd, 22037ec681f3Smrg struct rendering_state *state) 22047ec681f3Smrg{ 22057ec681f3Smrg int i; 22067ec681f3Smrg struct VkCopyBufferToImageInfo2KHR *copycmd = cmd->u.copy_buffer_to_image2_khr.copy_buffer_to_image_info; 22077ec681f3Smrg LVP_FROM_HANDLE(lvp_image, dst_image, copycmd->dstImage); 22087ec681f3Smrg struct pipe_box box, sbox; 22097ec681f3Smrg struct pipe_transfer *src_t, *dst_t; 22107ec681f3Smrg void *src_data, *dst_data; 22117ec681f3Smrg 22127ec681f3Smrg state->pctx->flush(state->pctx, NULL, 0); 22137ec681f3Smrg 22147ec681f3Smrg for (i = 0; i < copycmd->regionCount; i++) { 22157ec681f3Smrg 22167ec681f3Smrg sbox.x = copycmd->pRegions[i].bufferOffset; 22177ec681f3Smrg sbox.y = 0; 22187ec681f3Smrg sbox.z = 0; 22197ec681f3Smrg sbox.width = lvp_buffer_from_handle(copycmd->srcBuffer)->bo->width0; 22207ec681f3Smrg sbox.height = 1; 22217ec681f3Smrg sbox.depth = 1; 22227ec681f3Smrg src_data = state->pctx->buffer_map(state->pctx, 22237ec681f3Smrg lvp_buffer_from_handle(copycmd->srcBuffer)->bo, 22247ec681f3Smrg 0, 22257ec681f3Smrg PIPE_MAP_READ, 22267ec681f3Smrg &sbox, 22277ec681f3Smrg &src_t); 22287ec681f3Smrg 22297ec681f3Smrg 22307ec681f3Smrg box.x = copycmd->pRegions[i].imageOffset.x; 22317ec681f3Smrg box.y = copycmd->pRegions[i].imageOffset.y; 22327ec681f3Smrg box.z = dst_image->vk.image_type == VK_IMAGE_TYPE_3D ? copycmd->pRegions[i].imageOffset.z : copycmd->pRegions[i].imageSubresource.baseArrayLayer; 22337ec681f3Smrg box.width = copycmd->pRegions[i].imageExtent.width; 22347ec681f3Smrg box.height = copycmd->pRegions[i].imageExtent.height; 22357ec681f3Smrg box.depth = dst_image->vk.image_type == VK_IMAGE_TYPE_3D ? copycmd->pRegions[i].imageExtent.depth : copycmd->pRegions[i].imageSubresource.layerCount; 22367ec681f3Smrg 22377ec681f3Smrg dst_data = state->pctx->texture_map(state->pctx, 22387ec681f3Smrg dst_image->bo, 22397ec681f3Smrg copycmd->pRegions[i].imageSubresource.mipLevel, 22407ec681f3Smrg PIPE_MAP_WRITE, 22417ec681f3Smrg &box, 22427ec681f3Smrg &dst_t); 22437ec681f3Smrg 22447ec681f3Smrg enum pipe_format dst_format = dst_image->bo->format; 22457ec681f3Smrg enum pipe_format src_format = dst_format; 22467ec681f3Smrg if (util_format_is_depth_or_stencil(dst_format)) { 22477ec681f3Smrg if (copycmd->pRegions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) { 22487ec681f3Smrg src_format = util_format_get_depth_only(dst_image->bo->format); 22497ec681f3Smrg } else if (copycmd->pRegions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) { 22507ec681f3Smrg src_format = PIPE_FORMAT_S8_UINT; 22517ec681f3Smrg } 22527ec681f3Smrg } 22537ec681f3Smrg 22547ec681f3Smrg unsigned buffer_row_len = util_format_get_stride(src_format, copycmd->pRegions[i].bufferRowLength); 22557ec681f3Smrg if (buffer_row_len == 0) 22567ec681f3Smrg buffer_row_len = util_format_get_stride(src_format, copycmd->pRegions[i].imageExtent.width); 22577ec681f3Smrg unsigned buffer_image_height = copycmd->pRegions[i].bufferImageHeight; 22587ec681f3Smrg if (buffer_image_height == 0) 22597ec681f3Smrg buffer_image_height = copycmd->pRegions[i].imageExtent.height; 22607ec681f3Smrg 22617ec681f3Smrg unsigned img_stride = util_format_get_2d_size(src_format, buffer_row_len, buffer_image_height); 22627ec681f3Smrg if (src_format != dst_format) { 22637ec681f3Smrg copy_depth_box(dst_data, dst_format, 22647ec681f3Smrg dst_t->stride, dst_t->layer_stride, 22657ec681f3Smrg 0, 0, 0, 22667ec681f3Smrg copycmd->pRegions[i].imageExtent.width, 22677ec681f3Smrg copycmd->pRegions[i].imageExtent.height, 22687ec681f3Smrg box.depth, 22697ec681f3Smrg src_data, src_format, 22707ec681f3Smrg buffer_row_len, img_stride, 0, 0, 0); 22717ec681f3Smrg } else { 22727ec681f3Smrg util_copy_box(dst_data, dst_format, 22737ec681f3Smrg dst_t->stride, dst_t->layer_stride, 22747ec681f3Smrg 0, 0, 0, 22757ec681f3Smrg copycmd->pRegions[i].imageExtent.width, 22767ec681f3Smrg copycmd->pRegions[i].imageExtent.height, 22777ec681f3Smrg box.depth, 22787ec681f3Smrg src_data, 22797ec681f3Smrg buffer_row_len, img_stride, 0, 0, 0); 22807ec681f3Smrg } 22817ec681f3Smrg state->pctx->buffer_unmap(state->pctx, src_t); 22827ec681f3Smrg state->pctx->texture_unmap(state->pctx, dst_t); 22837ec681f3Smrg } 22847ec681f3Smrg} 22857ec681f3Smrg 22867ec681f3Smrgstatic void handle_copy_image(struct vk_cmd_queue_entry *cmd, 22877ec681f3Smrg struct rendering_state *state) 22887ec681f3Smrg{ 22897ec681f3Smrg int i; 22907ec681f3Smrg struct VkCopyImageInfo2KHR *copycmd = cmd->u.copy_image2_khr.copy_image_info; 22917ec681f3Smrg LVP_FROM_HANDLE(lvp_image, src_image, copycmd->srcImage); 22927ec681f3Smrg LVP_FROM_HANDLE(lvp_image, dst_image, copycmd->dstImage); 22937ec681f3Smrg 22947ec681f3Smrg state->pctx->flush(state->pctx, NULL, 0); 22957ec681f3Smrg 22967ec681f3Smrg for (i = 0; i < copycmd->regionCount; i++) { 22977ec681f3Smrg struct pipe_box src_box; 22987ec681f3Smrg src_box.x = copycmd->pRegions[i].srcOffset.x; 22997ec681f3Smrg src_box.y = copycmd->pRegions[i].srcOffset.y; 23007ec681f3Smrg src_box.width = copycmd->pRegions[i].extent.width; 23017ec681f3Smrg src_box.height = copycmd->pRegions[i].extent.height; 23027ec681f3Smrg if (src_image->bo->target == PIPE_TEXTURE_3D) { 23037ec681f3Smrg src_box.depth = copycmd->pRegions[i].extent.depth; 23047ec681f3Smrg src_box.z = copycmd->pRegions[i].srcOffset.z; 23057ec681f3Smrg } else { 23067ec681f3Smrg src_box.depth = copycmd->pRegions[i].srcSubresource.layerCount; 23077ec681f3Smrg src_box.z = copycmd->pRegions[i].srcSubresource.baseArrayLayer; 23087ec681f3Smrg } 23097ec681f3Smrg 23107ec681f3Smrg unsigned dstz = dst_image->bo->target == PIPE_TEXTURE_3D ? 23117ec681f3Smrg copycmd->pRegions[i].dstOffset.z : 23127ec681f3Smrg copycmd->pRegions[i].dstSubresource.baseArrayLayer; 23137ec681f3Smrg state->pctx->resource_copy_region(state->pctx, dst_image->bo, 23147ec681f3Smrg copycmd->pRegions[i].dstSubresource.mipLevel, 23157ec681f3Smrg copycmd->pRegions[i].dstOffset.x, 23167ec681f3Smrg copycmd->pRegions[i].dstOffset.y, 23177ec681f3Smrg dstz, 23187ec681f3Smrg src_image->bo, 23197ec681f3Smrg copycmd->pRegions[i].srcSubresource.mipLevel, 23207ec681f3Smrg &src_box); 23217ec681f3Smrg } 23227ec681f3Smrg} 23237ec681f3Smrg 23247ec681f3Smrgstatic void handle_copy_buffer(struct vk_cmd_queue_entry *cmd, 23257ec681f3Smrg struct rendering_state *state) 23267ec681f3Smrg{ 23277ec681f3Smrg int i; 23287ec681f3Smrg struct VkCopyBufferInfo2KHR *copycmd = cmd->u.copy_buffer2_khr.copy_buffer_info; 23297ec681f3Smrg 23307ec681f3Smrg for (i = 0; i < copycmd->regionCount; i++) { 23317ec681f3Smrg struct pipe_box box = { 0 }; 23327ec681f3Smrg u_box_1d(copycmd->pRegions[i].srcOffset, copycmd->pRegions[i].size, &box); 23337ec681f3Smrg state->pctx->resource_copy_region(state->pctx, lvp_buffer_from_handle(copycmd->dstBuffer)->bo, 0, 23347ec681f3Smrg copycmd->pRegions[i].dstOffset, 0, 0, 23357ec681f3Smrg lvp_buffer_from_handle(copycmd->srcBuffer)->bo, 0, &box); 23367ec681f3Smrg } 23377ec681f3Smrg} 23387ec681f3Smrg 23397ec681f3Smrgstatic void handle_blit_image(struct vk_cmd_queue_entry *cmd, 23407ec681f3Smrg struct rendering_state *state) 23417ec681f3Smrg{ 23427ec681f3Smrg int i; 23437ec681f3Smrg struct VkBlitImageInfo2KHR *blitcmd = cmd->u.blit_image2_khr.blit_image_info; 23447ec681f3Smrg LVP_FROM_HANDLE(lvp_image, src_image, blitcmd->srcImage); 23457ec681f3Smrg LVP_FROM_HANDLE(lvp_image, dst_image, blitcmd->dstImage); 23467ec681f3Smrg struct pipe_blit_info info; 23477ec681f3Smrg 23487ec681f3Smrg memset(&info, 0, sizeof(info)); 23497ec681f3Smrg 23507ec681f3Smrg state->pctx->flush(state->pctx, NULL, 0); 23517ec681f3Smrg info.src.resource = src_image->bo; 23527ec681f3Smrg info.dst.resource = dst_image->bo; 23537ec681f3Smrg info.src.format = src_image->bo->format; 23547ec681f3Smrg info.dst.format = dst_image->bo->format; 23557ec681f3Smrg info.mask = util_format_is_depth_or_stencil(info.src.format) ? PIPE_MASK_ZS : PIPE_MASK_RGBA; 23567ec681f3Smrg info.filter = blitcmd->filter == VK_FILTER_NEAREST ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR; 23577ec681f3Smrg for (i = 0; i < blitcmd->regionCount; i++) { 23587ec681f3Smrg int srcX0, srcX1, srcY0, srcY1, srcZ0, srcZ1; 23597ec681f3Smrg unsigned dstX0, dstX1, dstY0, dstY1, dstZ0, dstZ1; 23607ec681f3Smrg 23617ec681f3Smrg srcX0 = blitcmd->pRegions[i].srcOffsets[0].x; 23627ec681f3Smrg srcX1 = blitcmd->pRegions[i].srcOffsets[1].x; 23637ec681f3Smrg srcY0 = blitcmd->pRegions[i].srcOffsets[0].y; 23647ec681f3Smrg srcY1 = blitcmd->pRegions[i].srcOffsets[1].y; 23657ec681f3Smrg srcZ0 = blitcmd->pRegions[i].srcOffsets[0].z; 23667ec681f3Smrg srcZ1 = blitcmd->pRegions[i].srcOffsets[1].z; 23677ec681f3Smrg 23687ec681f3Smrg dstX0 = blitcmd->pRegions[i].dstOffsets[0].x; 23697ec681f3Smrg dstX1 = blitcmd->pRegions[i].dstOffsets[1].x; 23707ec681f3Smrg dstY0 = blitcmd->pRegions[i].dstOffsets[0].y; 23717ec681f3Smrg dstY1 = blitcmd->pRegions[i].dstOffsets[1].y; 23727ec681f3Smrg dstZ0 = blitcmd->pRegions[i].dstOffsets[0].z; 23737ec681f3Smrg dstZ1 = blitcmd->pRegions[i].dstOffsets[1].z; 23747ec681f3Smrg 23757ec681f3Smrg if (dstX0 < dstX1) { 23767ec681f3Smrg info.dst.box.x = dstX0; 23777ec681f3Smrg info.src.box.x = srcX0; 23787ec681f3Smrg info.dst.box.width = dstX1 - dstX0; 23797ec681f3Smrg info.src.box.width = srcX1 - srcX0; 23807ec681f3Smrg } else { 23817ec681f3Smrg info.dst.box.x = dstX1; 23827ec681f3Smrg info.src.box.x = srcX1; 23837ec681f3Smrg info.dst.box.width = dstX0 - dstX1; 23847ec681f3Smrg info.src.box.width = srcX0 - srcX1; 23857ec681f3Smrg } 23867ec681f3Smrg 23877ec681f3Smrg if (dstY0 < dstY1) { 23887ec681f3Smrg info.dst.box.y = dstY0; 23897ec681f3Smrg info.src.box.y = srcY0; 23907ec681f3Smrg info.dst.box.height = dstY1 - dstY0; 23917ec681f3Smrg info.src.box.height = srcY1 - srcY0; 23927ec681f3Smrg } else { 23937ec681f3Smrg info.dst.box.y = dstY1; 23947ec681f3Smrg info.src.box.y = srcY1; 23957ec681f3Smrg info.dst.box.height = dstY0 - dstY1; 23967ec681f3Smrg info.src.box.height = srcY0 - srcY1; 23977ec681f3Smrg } 23987ec681f3Smrg 23997ec681f3Smrg assert_subresource_layers(info.src.resource, &blitcmd->pRegions[i].srcSubresource, blitcmd->pRegions[i].srcOffsets); 24007ec681f3Smrg assert_subresource_layers(info.dst.resource, &blitcmd->pRegions[i].dstSubresource, blitcmd->pRegions[i].dstOffsets); 24017ec681f3Smrg if (src_image->bo->target == PIPE_TEXTURE_3D) { 24027ec681f3Smrg if (dstZ0 < dstZ1) { 24037ec681f3Smrg info.dst.box.z = dstZ0; 24047ec681f3Smrg info.src.box.z = srcZ0; 24057ec681f3Smrg info.dst.box.depth = dstZ1 - dstZ0; 24067ec681f3Smrg info.src.box.depth = srcZ1 - srcZ0; 24077ec681f3Smrg } else { 24087ec681f3Smrg info.dst.box.z = dstZ1; 24097ec681f3Smrg info.src.box.z = srcZ1; 24107ec681f3Smrg info.dst.box.depth = dstZ0 - dstZ1; 24117ec681f3Smrg info.src.box.depth = srcZ0 - srcZ1; 24127ec681f3Smrg } 24137ec681f3Smrg } else { 24147ec681f3Smrg info.src.box.z = blitcmd->pRegions[i].srcSubresource.baseArrayLayer; 24157ec681f3Smrg info.dst.box.z = blitcmd->pRegions[i].dstSubresource.baseArrayLayer; 24167ec681f3Smrg info.src.box.depth = blitcmd->pRegions[i].srcSubresource.layerCount; 24177ec681f3Smrg info.dst.box.depth = blitcmd->pRegions[i].dstSubresource.layerCount; 24187ec681f3Smrg } 24197ec681f3Smrg 24207ec681f3Smrg info.src.level = blitcmd->pRegions[i].srcSubresource.mipLevel; 24217ec681f3Smrg info.dst.level = blitcmd->pRegions[i].dstSubresource.mipLevel; 24227ec681f3Smrg state->pctx->blit(state->pctx, &info); 24237ec681f3Smrg } 24247ec681f3Smrg} 24257ec681f3Smrg 24267ec681f3Smrgstatic void handle_fill_buffer(struct vk_cmd_queue_entry *cmd, 24277ec681f3Smrg struct rendering_state *state) 24287ec681f3Smrg{ 24297ec681f3Smrg struct vk_cmd_fill_buffer *fillcmd = &cmd->u.fill_buffer; 24307ec681f3Smrg uint32_t size = fillcmd->size; 24317ec681f3Smrg 24327ec681f3Smrg if (fillcmd->size == VK_WHOLE_SIZE) { 24337ec681f3Smrg size = lvp_buffer_from_handle(fillcmd->dst_buffer)->bo->width0 - fillcmd->dst_offset; 24347ec681f3Smrg size = ROUND_DOWN_TO(size, 4); 24357ec681f3Smrg } 24367ec681f3Smrg 24377ec681f3Smrg state->pctx->clear_buffer(state->pctx, 24387ec681f3Smrg lvp_buffer_from_handle(fillcmd->dst_buffer)->bo, 24397ec681f3Smrg fillcmd->dst_offset, 24407ec681f3Smrg size, 24417ec681f3Smrg &fillcmd->data, 24427ec681f3Smrg 4); 24437ec681f3Smrg} 24447ec681f3Smrg 24457ec681f3Smrgstatic void handle_update_buffer(struct vk_cmd_queue_entry *cmd, 24467ec681f3Smrg struct rendering_state *state) 24477ec681f3Smrg{ 24487ec681f3Smrg struct vk_cmd_update_buffer *updcmd = &cmd->u.update_buffer; 24497ec681f3Smrg uint32_t *dst; 24507ec681f3Smrg struct pipe_transfer *dst_t; 24517ec681f3Smrg struct pipe_box box; 24527ec681f3Smrg 24537ec681f3Smrg u_box_1d(updcmd->dst_offset, updcmd->data_size, &box); 24547ec681f3Smrg dst = state->pctx->buffer_map(state->pctx, 24557ec681f3Smrg lvp_buffer_from_handle(updcmd->dst_buffer)->bo, 24567ec681f3Smrg 0, 24577ec681f3Smrg PIPE_MAP_WRITE, 24587ec681f3Smrg &box, 24597ec681f3Smrg &dst_t); 24607ec681f3Smrg 24617ec681f3Smrg memcpy(dst, updcmd->data, updcmd->data_size); 24627ec681f3Smrg state->pctx->buffer_unmap(state->pctx, dst_t); 24637ec681f3Smrg} 24647ec681f3Smrg 24657ec681f3Smrgstatic void handle_draw_indexed(struct vk_cmd_queue_entry *cmd, 24667ec681f3Smrg struct rendering_state *state) 24677ec681f3Smrg{ 24687ec681f3Smrg const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass]; 24697ec681f3Smrg struct pipe_draw_start_count_bias draw = {0}; 24707ec681f3Smrg 24717ec681f3Smrg state->info.index_bounds_valid = false; 24727ec681f3Smrg state->info.min_index = 0; 24737ec681f3Smrg state->info.max_index = ~0; 24747ec681f3Smrg state->info.index_size = state->index_size; 24757ec681f3Smrg state->info.index.resource = state->index_buffer; 24767ec681f3Smrg state->info.start_instance = cmd->u.draw_indexed.first_instance; 24777ec681f3Smrg state->info.instance_count = cmd->u.draw_indexed.instance_count; 24787ec681f3Smrg state->info.view_mask = subpass->view_mask; 24797ec681f3Smrg 24807ec681f3Smrg if (state->info.primitive_restart) 24817ec681f3Smrg state->info.restart_index = util_prim_restart_index_from_size(state->info.index_size); 24827ec681f3Smrg 24837ec681f3Smrg draw.count = cmd->u.draw_indexed.index_count; 24847ec681f3Smrg draw.index_bias = cmd->u.draw_indexed.vertex_offset; 24857ec681f3Smrg /* TODO: avoid calculating multiple times if cmdbuf is submitted again */ 24867ec681f3Smrg draw.start = (state->index_offset / state->index_size) + cmd->u.draw_indexed.first_index; 24877ec681f3Smrg 24887ec681f3Smrg state->info.index_bias_varies = !cmd->u.draw_indexed.vertex_offset; 24897ec681f3Smrg state->pctx->set_patch_vertices(state->pctx, state->patch_vertices); 24907ec681f3Smrg state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, &draw, 1); 24917ec681f3Smrg} 24927ec681f3Smrg 24937ec681f3Smrgstatic void handle_draw_multi_indexed(struct vk_cmd_queue_entry *cmd, 24947ec681f3Smrg struct rendering_state *state) 24957ec681f3Smrg{ 24967ec681f3Smrg const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass]; 24977ec681f3Smrg struct pipe_draw_start_count_bias *draws = calloc(cmd->u.draw_multi_indexed_ext.draw_count, 24987ec681f3Smrg sizeof(*draws)); 24997ec681f3Smrg 25007ec681f3Smrg state->info.index_bounds_valid = false; 25017ec681f3Smrg state->info.min_index = 0; 25027ec681f3Smrg state->info.max_index = ~0; 25037ec681f3Smrg state->info.index_size = state->index_size; 25047ec681f3Smrg state->info.index.resource = state->index_buffer; 25057ec681f3Smrg state->info.start_instance = cmd->u.draw_multi_indexed_ext.first_instance; 25067ec681f3Smrg state->info.instance_count = cmd->u.draw_multi_indexed_ext.instance_count; 25077ec681f3Smrg state->info.view_mask = subpass->view_mask; 25087ec681f3Smrg if (cmd->u.draw_multi_indexed_ext.draw_count > 1) 25097ec681f3Smrg state->info.increment_draw_id = true; 25107ec681f3Smrg 25117ec681f3Smrg if (state->info.primitive_restart) 25127ec681f3Smrg state->info.restart_index = util_prim_restart_index_from_size(state->info.index_size); 25137ec681f3Smrg 25147ec681f3Smrg unsigned size = cmd->u.draw_multi_indexed_ext.draw_count * sizeof(struct pipe_draw_start_count_bias); 25157ec681f3Smrg memcpy(draws, cmd->u.draw_multi_indexed_ext.index_info, size); 25167ec681f3Smrg 25177ec681f3Smrg /* only the first member is read if index_bias_varies is true */ 25187ec681f3Smrg if (cmd->u.draw_multi_indexed_ext.draw_count && 25197ec681f3Smrg cmd->u.draw_multi_indexed_ext.vertex_offset) 25207ec681f3Smrg draws[0].index_bias = *cmd->u.draw_multi_indexed_ext.vertex_offset; 25217ec681f3Smrg 25227ec681f3Smrg /* TODO: avoid calculating multiple times if cmdbuf is submitted again */ 25237ec681f3Smrg for (unsigned i = 0; i < cmd->u.draw_multi_indexed_ext.draw_count; i++) 25247ec681f3Smrg draws[i].start = (state->index_offset / state->index_size) + draws[i].start; 25257ec681f3Smrg 25267ec681f3Smrg state->info.index_bias_varies = !cmd->u.draw_multi_indexed_ext.vertex_offset; 25277ec681f3Smrg state->pctx->set_patch_vertices(state->pctx, state->patch_vertices); 25287ec681f3Smrg 25297ec681f3Smrg if (cmd->u.draw_multi_indexed_ext.draw_count) 25307ec681f3Smrg state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, draws, cmd->u.draw_multi_indexed_ext.draw_count); 25317ec681f3Smrg 25327ec681f3Smrg free(draws); 25337ec681f3Smrg} 25347ec681f3Smrg 25357ec681f3Smrgstatic void handle_draw_indirect(struct vk_cmd_queue_entry *cmd, 25367ec681f3Smrg struct rendering_state *state, bool indexed) 25377ec681f3Smrg{ 25387ec681f3Smrg const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass]; 25397ec681f3Smrg struct pipe_draw_start_count_bias draw = {0}; 25407ec681f3Smrg if (indexed) { 25417ec681f3Smrg state->info.index_bounds_valid = false; 25427ec681f3Smrg state->info.index_size = state->index_size; 25437ec681f3Smrg state->info.index.resource = state->index_buffer; 25447ec681f3Smrg state->info.max_index = ~0; 25457ec681f3Smrg if (state->info.primitive_restart) 25467ec681f3Smrg state->info.restart_index = util_prim_restart_index_from_size(state->info.index_size); 25477ec681f3Smrg } else 25487ec681f3Smrg state->info.index_size = 0; 25497ec681f3Smrg state->indirect_info.offset = cmd->u.draw_indirect.offset; 25507ec681f3Smrg state->indirect_info.stride = cmd->u.draw_indirect.stride; 25517ec681f3Smrg state->indirect_info.draw_count = cmd->u.draw_indirect.draw_count; 25527ec681f3Smrg state->indirect_info.buffer = lvp_buffer_from_handle(cmd->u.draw_indirect.buffer)->bo; 25537ec681f3Smrg state->info.view_mask = subpass->view_mask; 25547ec681f3Smrg 25557ec681f3Smrg state->pctx->set_patch_vertices(state->pctx, state->patch_vertices); 25567ec681f3Smrg state->pctx->draw_vbo(state->pctx, &state->info, 0, &state->indirect_info, &draw, 1); 25577ec681f3Smrg} 25587ec681f3Smrg 25597ec681f3Smrgstatic void handle_index_buffer(struct vk_cmd_queue_entry *cmd, 25607ec681f3Smrg struct rendering_state *state) 25617ec681f3Smrg{ 25627ec681f3Smrg struct vk_cmd_bind_index_buffer *ib = &cmd->u.bind_index_buffer; 25637ec681f3Smrg switch (ib->index_type) { 25647ec681f3Smrg case VK_INDEX_TYPE_UINT8_EXT: 25657ec681f3Smrg state->index_size = 1; 25667ec681f3Smrg break; 25677ec681f3Smrg case VK_INDEX_TYPE_UINT16: 25687ec681f3Smrg state->index_size = 2; 25697ec681f3Smrg break; 25707ec681f3Smrg case VK_INDEX_TYPE_UINT32: 25717ec681f3Smrg state->index_size = 4; 25727ec681f3Smrg break; 25737ec681f3Smrg default: 25747ec681f3Smrg break; 25757ec681f3Smrg } 25767ec681f3Smrg state->index_offset = ib->offset; 25777ec681f3Smrg if (ib->buffer) 25787ec681f3Smrg state->index_buffer = lvp_buffer_from_handle(ib->buffer)->bo; 25797ec681f3Smrg else 25807ec681f3Smrg state->index_buffer = NULL; 25817ec681f3Smrg 25827ec681f3Smrg state->ib_dirty = true; 25837ec681f3Smrg} 25847ec681f3Smrg 25857ec681f3Smrgstatic void handle_dispatch(struct vk_cmd_queue_entry *cmd, 25867ec681f3Smrg struct rendering_state *state) 25877ec681f3Smrg{ 25887ec681f3Smrg state->dispatch_info.grid[0] = cmd->u.dispatch.group_count_x; 25897ec681f3Smrg state->dispatch_info.grid[1] = cmd->u.dispatch.group_count_y; 25907ec681f3Smrg state->dispatch_info.grid[2] = cmd->u.dispatch.group_count_z; 25917ec681f3Smrg state->dispatch_info.grid_base[0] = 0; 25927ec681f3Smrg state->dispatch_info.grid_base[1] = 0; 25937ec681f3Smrg state->dispatch_info.grid_base[2] = 0; 25947ec681f3Smrg state->dispatch_info.indirect = NULL; 25957ec681f3Smrg state->pctx->launch_grid(state->pctx, &state->dispatch_info); 25967ec681f3Smrg} 25977ec681f3Smrg 25987ec681f3Smrgstatic void handle_dispatch_base(struct vk_cmd_queue_entry *cmd, 25997ec681f3Smrg struct rendering_state *state) 26007ec681f3Smrg{ 26017ec681f3Smrg state->dispatch_info.grid[0] = cmd->u.dispatch_base.group_count_x; 26027ec681f3Smrg state->dispatch_info.grid[1] = cmd->u.dispatch_base.group_count_y; 26037ec681f3Smrg state->dispatch_info.grid[2] = cmd->u.dispatch_base.group_count_z; 26047ec681f3Smrg state->dispatch_info.grid_base[0] = cmd->u.dispatch_base.base_group_x; 26057ec681f3Smrg state->dispatch_info.grid_base[1] = cmd->u.dispatch_base.base_group_y; 26067ec681f3Smrg state->dispatch_info.grid_base[2] = cmd->u.dispatch_base.base_group_z; 26077ec681f3Smrg state->dispatch_info.indirect = NULL; 26087ec681f3Smrg state->pctx->launch_grid(state->pctx, &state->dispatch_info); 26097ec681f3Smrg} 26107ec681f3Smrg 26117ec681f3Smrgstatic void handle_dispatch_indirect(struct vk_cmd_queue_entry *cmd, 26127ec681f3Smrg struct rendering_state *state) 26137ec681f3Smrg{ 26147ec681f3Smrg state->dispatch_info.indirect = lvp_buffer_from_handle(cmd->u.dispatch_indirect.buffer)->bo; 26157ec681f3Smrg state->dispatch_info.indirect_offset = cmd->u.dispatch_indirect.offset; 26167ec681f3Smrg state->pctx->launch_grid(state->pctx, &state->dispatch_info); 26177ec681f3Smrg} 26187ec681f3Smrg 26197ec681f3Smrgstatic void handle_push_constants(struct vk_cmd_queue_entry *cmd, 26207ec681f3Smrg struct rendering_state *state) 26217ec681f3Smrg{ 26227ec681f3Smrg memcpy(state->push_constants + cmd->u.push_constants.offset, cmd->u.push_constants.values, cmd->u.push_constants.size); 26237ec681f3Smrg 26247ec681f3Smrg state->pc_buffer[PIPE_SHADER_VERTEX].buffer_size = 128 * 4; 26257ec681f3Smrg state->pc_buffer[PIPE_SHADER_VERTEX].buffer_offset = 0; 26267ec681f3Smrg state->pc_buffer[PIPE_SHADER_VERTEX].user_buffer = state->push_constants; 26277ec681f3Smrg state->pcbuf_dirty[PIPE_SHADER_VERTEX] = true; 26287ec681f3Smrg state->pc_buffer[PIPE_SHADER_FRAGMENT].buffer_size = 128 * 4; 26297ec681f3Smrg state->pc_buffer[PIPE_SHADER_FRAGMENT].buffer_offset = 0; 26307ec681f3Smrg state->pc_buffer[PIPE_SHADER_FRAGMENT].user_buffer = state->push_constants; 26317ec681f3Smrg state->pcbuf_dirty[PIPE_SHADER_FRAGMENT] = true; 26327ec681f3Smrg state->pc_buffer[PIPE_SHADER_GEOMETRY].buffer_size = 128 * 4; 26337ec681f3Smrg state->pc_buffer[PIPE_SHADER_GEOMETRY].buffer_offset = 0; 26347ec681f3Smrg state->pc_buffer[PIPE_SHADER_GEOMETRY].user_buffer = state->push_constants; 26357ec681f3Smrg state->pcbuf_dirty[PIPE_SHADER_GEOMETRY] = true; 26367ec681f3Smrg state->pc_buffer[PIPE_SHADER_TESS_CTRL].buffer_size = 128 * 4; 26377ec681f3Smrg state->pc_buffer[PIPE_SHADER_TESS_CTRL].buffer_offset = 0; 26387ec681f3Smrg state->pc_buffer[PIPE_SHADER_TESS_CTRL].user_buffer = state->push_constants; 26397ec681f3Smrg state->pcbuf_dirty[PIPE_SHADER_TESS_CTRL] = true; 26407ec681f3Smrg state->pc_buffer[PIPE_SHADER_TESS_EVAL].buffer_size = 128 * 4; 26417ec681f3Smrg state->pc_buffer[PIPE_SHADER_TESS_EVAL].buffer_offset = 0; 26427ec681f3Smrg state->pc_buffer[PIPE_SHADER_TESS_EVAL].user_buffer = state->push_constants; 26437ec681f3Smrg state->pcbuf_dirty[PIPE_SHADER_TESS_EVAL] = true; 26447ec681f3Smrg state->pc_buffer[PIPE_SHADER_COMPUTE].buffer_size = 128 * 4; 26457ec681f3Smrg state->pc_buffer[PIPE_SHADER_COMPUTE].buffer_offset = 0; 26467ec681f3Smrg state->pc_buffer[PIPE_SHADER_COMPUTE].user_buffer = state->push_constants; 26477ec681f3Smrg state->pcbuf_dirty[PIPE_SHADER_COMPUTE] = true; 26487ec681f3Smrg} 26497ec681f3Smrg 26507ec681f3Smrgstatic void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer, 26517ec681f3Smrg struct rendering_state *state); 26527ec681f3Smrg 26537ec681f3Smrgstatic void handle_execute_commands(struct vk_cmd_queue_entry *cmd, 26547ec681f3Smrg struct rendering_state *state) 26557ec681f3Smrg{ 26567ec681f3Smrg for (unsigned i = 0; i < cmd->u.execute_commands.command_buffer_count; i++) { 26577ec681f3Smrg LVP_FROM_HANDLE(lvp_cmd_buffer, secondary_buf, cmd->u.execute_commands.command_buffers[i]); 26587ec681f3Smrg lvp_execute_cmd_buffer(secondary_buf, state); 26597ec681f3Smrg } 26607ec681f3Smrg} 26617ec681f3Smrg 26627ec681f3Smrgstatic void handle_event_set(struct vk_cmd_queue_entry *cmd, 26637ec681f3Smrg struct rendering_state *state) 26647ec681f3Smrg{ 26657ec681f3Smrg LVP_FROM_HANDLE(lvp_event, event, cmd->u.set_event.event); 26667ec681f3Smrg 26677ec681f3Smrg if (cmd->u.reset_event.stage_mask == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT) 26687ec681f3Smrg state->pctx->flush(state->pctx, NULL, 0); 26697ec681f3Smrg event->event_storage = 1; 26707ec681f3Smrg} 26717ec681f3Smrg 26727ec681f3Smrgstatic void handle_event_reset(struct vk_cmd_queue_entry *cmd, 26737ec681f3Smrg struct rendering_state *state) 26747ec681f3Smrg{ 26757ec681f3Smrg LVP_FROM_HANDLE(lvp_event, event, cmd->u.reset_event.event); 26767ec681f3Smrg 26777ec681f3Smrg if (cmd->u.reset_event.stage_mask == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT) 26787ec681f3Smrg state->pctx->flush(state->pctx, NULL, 0); 26797ec681f3Smrg event->event_storage = 0; 26807ec681f3Smrg} 26817ec681f3Smrg 26827ec681f3Smrgstatic void handle_wait_events(struct vk_cmd_queue_entry *cmd, 26837ec681f3Smrg struct rendering_state *state) 26847ec681f3Smrg{ 26857ec681f3Smrg for (unsigned i = 0; i < cmd->u.wait_events.event_count; i++) { 26867ec681f3Smrg LVP_FROM_HANDLE(lvp_event, event, cmd->u.wait_events.events[i]); 26877ec681f3Smrg 26887ec681f3Smrg while (event->event_storage != true); 26897ec681f3Smrg } 26907ec681f3Smrg} 26917ec681f3Smrg 26927ec681f3Smrgstatic void handle_pipeline_barrier(struct vk_cmd_queue_entry *cmd, 26937ec681f3Smrg struct rendering_state *state) 26947ec681f3Smrg{ 26957ec681f3Smrg /* why hello nail, I'm a hammer. - TODO */ 26967ec681f3Smrg state->pctx->flush(state->pctx, NULL, 0); 26977ec681f3Smrg} 26987ec681f3Smrg 26997ec681f3Smrgstatic void handle_begin_query(struct vk_cmd_queue_entry *cmd, 27007ec681f3Smrg struct rendering_state *state) 27017ec681f3Smrg{ 27027ec681f3Smrg struct vk_cmd_begin_query *qcmd = &cmd->u.begin_query; 27037ec681f3Smrg LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool); 27047ec681f3Smrg 27057ec681f3Smrg if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS && 27067ec681f3Smrg pool->pipeline_stats & VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT) 27077ec681f3Smrg emit_compute_state(state); 27087ec681f3Smrg 27097ec681f3Smrg emit_state(state); 27107ec681f3Smrg 27117ec681f3Smrg if (!pool->queries[qcmd->query]) { 27127ec681f3Smrg enum pipe_query_type qtype = pool->base_type; 27137ec681f3Smrg pool->queries[qcmd->query] = state->pctx->create_query(state->pctx, 27147ec681f3Smrg qtype, 0); 27157ec681f3Smrg } 27167ec681f3Smrg 27177ec681f3Smrg state->pctx->begin_query(state->pctx, pool->queries[qcmd->query]); 27187ec681f3Smrg} 27197ec681f3Smrg 27207ec681f3Smrgstatic void handle_end_query(struct vk_cmd_queue_entry *cmd, 27217ec681f3Smrg struct rendering_state *state) 27227ec681f3Smrg{ 27237ec681f3Smrg struct vk_cmd_end_query *qcmd = &cmd->u.end_query; 27247ec681f3Smrg LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool); 27257ec681f3Smrg assert(pool->queries[qcmd->query]); 27267ec681f3Smrg 27277ec681f3Smrg state->pctx->end_query(state->pctx, pool->queries[qcmd->query]); 27287ec681f3Smrg} 27297ec681f3Smrg 27307ec681f3Smrg 27317ec681f3Smrgstatic void handle_begin_query_indexed_ext(struct vk_cmd_queue_entry *cmd, 27327ec681f3Smrg struct rendering_state *state) 27337ec681f3Smrg{ 27347ec681f3Smrg struct vk_cmd_begin_query_indexed_ext *qcmd = &cmd->u.begin_query_indexed_ext; 27357ec681f3Smrg LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool); 27367ec681f3Smrg 27377ec681f3Smrg if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS && 27387ec681f3Smrg pool->pipeline_stats & VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT) 27397ec681f3Smrg emit_compute_state(state); 27407ec681f3Smrg 27417ec681f3Smrg emit_state(state); 27427ec681f3Smrg 27437ec681f3Smrg if (!pool->queries[qcmd->query]) { 27447ec681f3Smrg enum pipe_query_type qtype = pool->base_type; 27457ec681f3Smrg pool->queries[qcmd->query] = state->pctx->create_query(state->pctx, 27467ec681f3Smrg qtype, qcmd->index); 27477ec681f3Smrg } 27487ec681f3Smrg 27497ec681f3Smrg state->pctx->begin_query(state->pctx, pool->queries[qcmd->query]); 27507ec681f3Smrg} 27517ec681f3Smrg 27527ec681f3Smrgstatic void handle_end_query_indexed_ext(struct vk_cmd_queue_entry *cmd, 27537ec681f3Smrg struct rendering_state *state) 27547ec681f3Smrg{ 27557ec681f3Smrg struct vk_cmd_end_query_indexed_ext *qcmd = &cmd->u.end_query_indexed_ext; 27567ec681f3Smrg LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool); 27577ec681f3Smrg assert(pool->queries[qcmd->query]); 27587ec681f3Smrg 27597ec681f3Smrg state->pctx->end_query(state->pctx, pool->queries[qcmd->query]); 27607ec681f3Smrg} 27617ec681f3Smrg 27627ec681f3Smrgstatic void handle_reset_query_pool(struct vk_cmd_queue_entry *cmd, 27637ec681f3Smrg struct rendering_state *state) 27647ec681f3Smrg{ 27657ec681f3Smrg struct vk_cmd_reset_query_pool *qcmd = &cmd->u.reset_query_pool; 27667ec681f3Smrg LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool); 27677ec681f3Smrg for (unsigned i = qcmd->first_query; i < qcmd->first_query + qcmd->query_count; i++) { 27687ec681f3Smrg if (pool->queries[i]) { 27697ec681f3Smrg state->pctx->destroy_query(state->pctx, pool->queries[i]); 27707ec681f3Smrg pool->queries[i] = NULL; 27717ec681f3Smrg } 27727ec681f3Smrg } 27737ec681f3Smrg} 27747ec681f3Smrg 27757ec681f3Smrgstatic void handle_write_timestamp(struct vk_cmd_queue_entry *cmd, 27767ec681f3Smrg struct rendering_state *state) 27777ec681f3Smrg{ 27787ec681f3Smrg struct vk_cmd_write_timestamp *qcmd = &cmd->u.write_timestamp; 27797ec681f3Smrg LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool); 27807ec681f3Smrg if (!pool->queries[qcmd->query]) { 27817ec681f3Smrg pool->queries[qcmd->query] = state->pctx->create_query(state->pctx, 27827ec681f3Smrg PIPE_QUERY_TIMESTAMP, 0); 27837ec681f3Smrg } 27847ec681f3Smrg 27857ec681f3Smrg if (!(qcmd->pipeline_stage == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)) 27867ec681f3Smrg state->pctx->flush(state->pctx, NULL, 0); 27877ec681f3Smrg state->pctx->end_query(state->pctx, pool->queries[qcmd->query]); 27887ec681f3Smrg 27897ec681f3Smrg} 27907ec681f3Smrg 27917ec681f3Smrgstatic void handle_copy_query_pool_results(struct vk_cmd_queue_entry *cmd, 27927ec681f3Smrg struct rendering_state *state) 27937ec681f3Smrg{ 27947ec681f3Smrg struct vk_cmd_copy_query_pool_results *copycmd = &cmd->u.copy_query_pool_results; 27957ec681f3Smrg LVP_FROM_HANDLE(lvp_query_pool, pool, copycmd->query_pool); 27967ec681f3Smrg 27977ec681f3Smrg for (unsigned i = copycmd->first_query; i < copycmd->first_query + copycmd->query_count; i++) { 27987ec681f3Smrg unsigned offset = copycmd->dst_offset + lvp_buffer_from_handle(copycmd->dst_buffer)->offset + (copycmd->stride * (i - copycmd->first_query)); 27997ec681f3Smrg if (pool->queries[i]) { 28007ec681f3Smrg if (copycmd->flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) 28017ec681f3Smrg state->pctx->get_query_result_resource(state->pctx, 28027ec681f3Smrg pool->queries[i], 28037ec681f3Smrg copycmd->flags & VK_QUERY_RESULT_WAIT_BIT, 28047ec681f3Smrg copycmd->flags & VK_QUERY_RESULT_64_BIT ? PIPE_QUERY_TYPE_U64 : PIPE_QUERY_TYPE_U32, 28057ec681f3Smrg -1, 28067ec681f3Smrg lvp_buffer_from_handle(copycmd->dst_buffer)->bo, 28077ec681f3Smrg offset + (copycmd->flags & VK_QUERY_RESULT_64_BIT ? 8 : 4)); 28087ec681f3Smrg if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS) { 28097ec681f3Smrg unsigned num_results = 0; 28107ec681f3Smrg unsigned result_size = copycmd->flags & VK_QUERY_RESULT_64_BIT ? 8 : 4; 28117ec681f3Smrg u_foreach_bit(bit, pool->pipeline_stats) 28127ec681f3Smrg state->pctx->get_query_result_resource(state->pctx, 28137ec681f3Smrg pool->queries[i], 28147ec681f3Smrg copycmd->flags & VK_QUERY_RESULT_WAIT_BIT, 28157ec681f3Smrg copycmd->flags & VK_QUERY_RESULT_64_BIT ? PIPE_QUERY_TYPE_U64 : PIPE_QUERY_TYPE_U32, 28167ec681f3Smrg bit, 28177ec681f3Smrg lvp_buffer_from_handle(copycmd->dst_buffer)->bo, 28187ec681f3Smrg offset + num_results++ * result_size); 28197ec681f3Smrg } else { 28207ec681f3Smrg state->pctx->get_query_result_resource(state->pctx, 28217ec681f3Smrg pool->queries[i], 28227ec681f3Smrg copycmd->flags & VK_QUERY_RESULT_WAIT_BIT, 28237ec681f3Smrg copycmd->flags & VK_QUERY_RESULT_64_BIT ? PIPE_QUERY_TYPE_U64 : PIPE_QUERY_TYPE_U32, 28247ec681f3Smrg 0, 28257ec681f3Smrg lvp_buffer_from_handle(copycmd->dst_buffer)->bo, 28267ec681f3Smrg offset); 28277ec681f3Smrg } 28287ec681f3Smrg } else { 28297ec681f3Smrg /* if no queries emitted yet, just reset the buffer to 0 so avail is reported correctly */ 28307ec681f3Smrg if (copycmd->flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) { 28317ec681f3Smrg struct pipe_transfer *src_t; 28327ec681f3Smrg uint32_t *map; 28337ec681f3Smrg 28347ec681f3Smrg struct pipe_box box = {0}; 28357ec681f3Smrg box.x = offset; 28367ec681f3Smrg box.width = copycmd->stride; 28377ec681f3Smrg box.height = 1; 28387ec681f3Smrg box.depth = 1; 28397ec681f3Smrg map = state->pctx->buffer_map(state->pctx, 28407ec681f3Smrg lvp_buffer_from_handle(copycmd->dst_buffer)->bo, 0, PIPE_MAP_READ, &box, 28417ec681f3Smrg &src_t); 28427ec681f3Smrg 28437ec681f3Smrg memset(map, 0, box.width); 28447ec681f3Smrg state->pctx->buffer_unmap(state->pctx, src_t); 28457ec681f3Smrg } 28467ec681f3Smrg } 28477ec681f3Smrg } 28487ec681f3Smrg} 28497ec681f3Smrg 28507ec681f3Smrgstatic void handle_clear_color_image(struct vk_cmd_queue_entry *cmd, 28517ec681f3Smrg struct rendering_state *state) 28527ec681f3Smrg{ 28537ec681f3Smrg LVP_FROM_HANDLE(lvp_image, image, cmd->u.clear_color_image.image); 28547ec681f3Smrg union util_color uc; 28557ec681f3Smrg uint32_t *col_val = uc.ui; 28567ec681f3Smrg util_pack_color_union(image->bo->format, &uc, (void*)cmd->u.clear_color_image.color); 28577ec681f3Smrg for (unsigned i = 0; i < cmd->u.clear_color_image.range_count; i++) { 28587ec681f3Smrg VkImageSubresourceRange *range = &cmd->u.clear_color_image.ranges[i]; 28597ec681f3Smrg struct pipe_box box; 28607ec681f3Smrg box.x = 0; 28617ec681f3Smrg box.y = 0; 28627ec681f3Smrg box.z = 0; 28637ec681f3Smrg 28647ec681f3Smrg uint32_t level_count = lvp_get_levelCount(image, range); 28657ec681f3Smrg for (unsigned j = range->baseMipLevel; j < range->baseMipLevel + level_count; j++) { 28667ec681f3Smrg box.width = u_minify(image->bo->width0, j); 28677ec681f3Smrg box.height = u_minify(image->bo->height0, j); 28687ec681f3Smrg box.depth = 1; 28697ec681f3Smrg if (image->bo->target == PIPE_TEXTURE_3D) 28707ec681f3Smrg box.depth = u_minify(image->bo->depth0, j); 28717ec681f3Smrg else if (image->bo->target == PIPE_TEXTURE_1D_ARRAY) { 28727ec681f3Smrg box.y = range->baseArrayLayer; 28737ec681f3Smrg box.height = lvp_get_layerCount(image, range); 28747ec681f3Smrg box.depth = 1; 28757ec681f3Smrg } else { 28767ec681f3Smrg box.z = range->baseArrayLayer; 28777ec681f3Smrg box.depth = lvp_get_layerCount(image, range); 28787ec681f3Smrg } 28797ec681f3Smrg 28807ec681f3Smrg state->pctx->clear_texture(state->pctx, image->bo, 28817ec681f3Smrg j, &box, (void *)col_val); 28827ec681f3Smrg } 28837ec681f3Smrg } 28847ec681f3Smrg} 28857ec681f3Smrg 28867ec681f3Smrgstatic void handle_clear_ds_image(struct vk_cmd_queue_entry *cmd, 28877ec681f3Smrg struct rendering_state *state) 28887ec681f3Smrg{ 28897ec681f3Smrg LVP_FROM_HANDLE(lvp_image, image, cmd->u.clear_depth_stencil_image.image); 28907ec681f3Smrg for (unsigned i = 0; i < cmd->u.clear_depth_stencil_image.range_count; i++) { 28917ec681f3Smrg VkImageSubresourceRange *range = &cmd->u.clear_depth_stencil_image.ranges[i]; 28927ec681f3Smrg uint32_t ds_clear_flags = 0; 28937ec681f3Smrg if (range->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) 28947ec681f3Smrg ds_clear_flags |= PIPE_CLEAR_DEPTH; 28957ec681f3Smrg if (range->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) 28967ec681f3Smrg ds_clear_flags |= PIPE_CLEAR_STENCIL; 28977ec681f3Smrg 28987ec681f3Smrg uint32_t level_count = lvp_get_levelCount(image, range); 28997ec681f3Smrg for (unsigned j = 0; j < level_count; j++) { 29007ec681f3Smrg struct pipe_surface *surf; 29017ec681f3Smrg unsigned width, height; 29027ec681f3Smrg 29037ec681f3Smrg width = u_minify(image->bo->width0, range->baseMipLevel + j); 29047ec681f3Smrg height = u_minify(image->bo->height0, range->baseMipLevel + j); 29057ec681f3Smrg 29067ec681f3Smrg surf = create_img_surface_bo(state, range, 29077ec681f3Smrg image->bo, image->bo->format, 29087ec681f3Smrg width, height, 29097ec681f3Smrg 0, lvp_get_layerCount(image, range) - 1, j); 29107ec681f3Smrg 29117ec681f3Smrg state->pctx->clear_depth_stencil(state->pctx, 29127ec681f3Smrg surf, 29137ec681f3Smrg ds_clear_flags, 29147ec681f3Smrg cmd->u.clear_depth_stencil_image.depth_stencil->depth, 29157ec681f3Smrg cmd->u.clear_depth_stencil_image.depth_stencil->stencil, 29167ec681f3Smrg 0, 0, 29177ec681f3Smrg width, height, true); 29187ec681f3Smrg state->pctx->surface_destroy(state->pctx, surf); 29197ec681f3Smrg } 29207ec681f3Smrg } 29217ec681f3Smrg} 29227ec681f3Smrg 29237ec681f3Smrgstatic void handle_clear_attachments(struct vk_cmd_queue_entry *cmd, 29247ec681f3Smrg struct rendering_state *state) 29257ec681f3Smrg{ 29267ec681f3Smrg for (uint32_t a = 0; a < cmd->u.clear_attachments.attachment_count; a++) { 29277ec681f3Smrg VkClearAttachment *att = &cmd->u.clear_attachments.attachments[a]; 29287ec681f3Smrg const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass]; 29297ec681f3Smrg struct lvp_image_view *imgv; 29307ec681f3Smrg 29317ec681f3Smrg if (att->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) { 29327ec681f3Smrg struct lvp_subpass_attachment *color_att = &subpass->color_attachments[att->colorAttachment]; 29337ec681f3Smrg if (!color_att || color_att->attachment == VK_ATTACHMENT_UNUSED) 29347ec681f3Smrg continue; 29357ec681f3Smrg imgv = get_attachment(state, color_att->attachment); 29367ec681f3Smrg } else { 29377ec681f3Smrg struct lvp_subpass_attachment *ds_att = subpass->depth_stencil_attachment; 29387ec681f3Smrg if (!ds_att || ds_att->attachment == VK_ATTACHMENT_UNUSED) 29397ec681f3Smrg continue; 29407ec681f3Smrg imgv = get_attachment(state, ds_att->attachment); 29417ec681f3Smrg } 29427ec681f3Smrg union pipe_color_union col_val; 29437ec681f3Smrg double dclear_val = 0; 29447ec681f3Smrg uint32_t sclear_val = 0; 29457ec681f3Smrg uint32_t ds_clear_flags = 0; 29467ec681f3Smrg if (att->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) { 29477ec681f3Smrg ds_clear_flags |= PIPE_CLEAR_DEPTH; 29487ec681f3Smrg dclear_val = att->clearValue.depthStencil.depth; 29497ec681f3Smrg } 29507ec681f3Smrg if (att->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) { 29517ec681f3Smrg ds_clear_flags |= PIPE_CLEAR_STENCIL; 29527ec681f3Smrg sclear_val = att->clearValue.depthStencil.stencil; 29537ec681f3Smrg } 29547ec681f3Smrg if (att->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { 29557ec681f3Smrg for (unsigned i = 0; i < 4; i++) 29567ec681f3Smrg col_val.ui[i] = att->clearValue.color.uint32[i]; 29577ec681f3Smrg } 29587ec681f3Smrg 29597ec681f3Smrg for (uint32_t r = 0; r < cmd->u.clear_attachments.rect_count; r++) { 29607ec681f3Smrg 29617ec681f3Smrg VkClearRect *rect = &cmd->u.clear_attachments.rects[r]; 29627ec681f3Smrg if (subpass->view_mask) { 29637ec681f3Smrg u_foreach_bit(i, subpass->view_mask) 29647ec681f3Smrg clear_attachment_layers(state, imgv, &rect->rect, 29657ec681f3Smrg i, 1, 29667ec681f3Smrg ds_clear_flags, dclear_val, sclear_val, 29677ec681f3Smrg &col_val); 29687ec681f3Smrg } else 29697ec681f3Smrg clear_attachment_layers(state, imgv, &rect->rect, 29707ec681f3Smrg rect->baseArrayLayer, rect->layerCount, 29717ec681f3Smrg ds_clear_flags, dclear_val, sclear_val, 29727ec681f3Smrg &col_val); 29737ec681f3Smrg } 29747ec681f3Smrg } 29757ec681f3Smrg} 29767ec681f3Smrg 29777ec681f3Smrgstatic void handle_resolve_image(struct vk_cmd_queue_entry *cmd, 29787ec681f3Smrg struct rendering_state *state) 29797ec681f3Smrg{ 29807ec681f3Smrg int i; 29817ec681f3Smrg struct VkResolveImageInfo2KHR *resolvecmd = cmd->u.resolve_image2_khr.resolve_image_info; 29827ec681f3Smrg LVP_FROM_HANDLE(lvp_image, src_image, resolvecmd->srcImage); 29837ec681f3Smrg LVP_FROM_HANDLE(lvp_image, dst_image, resolvecmd->dstImage); 29847ec681f3Smrg struct pipe_blit_info info; 29857ec681f3Smrg 29867ec681f3Smrg memset(&info, 0, sizeof(info)); 29877ec681f3Smrg 29887ec681f3Smrg state->pctx->flush(state->pctx, NULL, 0); 29897ec681f3Smrg info.src.resource = src_image->bo; 29907ec681f3Smrg info.dst.resource = dst_image->bo; 29917ec681f3Smrg info.src.format = src_image->bo->format; 29927ec681f3Smrg info.dst.format = dst_image->bo->format; 29937ec681f3Smrg info.mask = util_format_is_depth_or_stencil(info.src.format) ? PIPE_MASK_ZS : PIPE_MASK_RGBA; 29947ec681f3Smrg info.filter = PIPE_TEX_FILTER_NEAREST; 29957ec681f3Smrg for (i = 0; i < resolvecmd->regionCount; i++) { 29967ec681f3Smrg int srcX0, srcY0; 29977ec681f3Smrg unsigned dstX0, dstY0; 29987ec681f3Smrg 29997ec681f3Smrg srcX0 = resolvecmd->pRegions[i].srcOffset.x; 30007ec681f3Smrg srcY0 = resolvecmd->pRegions[i].srcOffset.y; 30017ec681f3Smrg 30027ec681f3Smrg dstX0 = resolvecmd->pRegions[i].dstOffset.x; 30037ec681f3Smrg dstY0 = resolvecmd->pRegions[i].dstOffset.y; 30047ec681f3Smrg 30057ec681f3Smrg info.dst.box.x = dstX0; 30067ec681f3Smrg info.dst.box.y = dstY0; 30077ec681f3Smrg info.src.box.x = srcX0; 30087ec681f3Smrg info.src.box.y = srcY0; 30097ec681f3Smrg 30107ec681f3Smrg info.dst.box.width = resolvecmd->pRegions[i].extent.width; 30117ec681f3Smrg info.src.box.width = resolvecmd->pRegions[i].extent.width; 30127ec681f3Smrg info.dst.box.height = resolvecmd->pRegions[i].extent.height; 30137ec681f3Smrg info.src.box.height = resolvecmd->pRegions[i].extent.height; 30147ec681f3Smrg 30157ec681f3Smrg info.dst.box.depth = resolvecmd->pRegions[i].dstSubresource.layerCount; 30167ec681f3Smrg info.src.box.depth = resolvecmd->pRegions[i].srcSubresource.layerCount; 30177ec681f3Smrg 30187ec681f3Smrg info.src.level = resolvecmd->pRegions[i].srcSubresource.mipLevel; 30197ec681f3Smrg info.src.box.z = resolvecmd->pRegions[i].srcOffset.z + resolvecmd->pRegions[i].srcSubresource.baseArrayLayer; 30207ec681f3Smrg 30217ec681f3Smrg info.dst.level = resolvecmd->pRegions[i].dstSubresource.mipLevel; 30227ec681f3Smrg info.dst.box.z = resolvecmd->pRegions[i].dstOffset.z + resolvecmd->pRegions[i].dstSubresource.baseArrayLayer; 30237ec681f3Smrg 30247ec681f3Smrg state->pctx->blit(state->pctx, &info); 30257ec681f3Smrg } 30267ec681f3Smrg} 30277ec681f3Smrg 30287ec681f3Smrgstatic void handle_draw_indirect_count(struct vk_cmd_queue_entry *cmd, 30297ec681f3Smrg struct rendering_state *state, bool indexed) 30307ec681f3Smrg{ 30317ec681f3Smrg const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass]; 30327ec681f3Smrg struct pipe_draw_start_count_bias draw = {0}; 30337ec681f3Smrg if (indexed) { 30347ec681f3Smrg state->info.index_bounds_valid = false; 30357ec681f3Smrg state->info.index_size = state->index_size; 30367ec681f3Smrg state->info.index.resource = state->index_buffer; 30377ec681f3Smrg state->info.max_index = ~0; 30387ec681f3Smrg } else 30397ec681f3Smrg state->info.index_size = 0; 30407ec681f3Smrg state->indirect_info.offset = cmd->u.draw_indirect_count.offset; 30417ec681f3Smrg state->indirect_info.stride = cmd->u.draw_indirect_count.stride; 30427ec681f3Smrg state->indirect_info.draw_count = cmd->u.draw_indirect_count.max_draw_count; 30437ec681f3Smrg state->indirect_info.buffer = lvp_buffer_from_handle(cmd->u.draw_indirect_count.buffer)->bo; 30447ec681f3Smrg state->indirect_info.indirect_draw_count_offset = cmd->u.draw_indirect_count.count_buffer_offset; 30457ec681f3Smrg state->indirect_info.indirect_draw_count = lvp_buffer_from_handle(cmd->u.draw_indirect_count.count_buffer)->bo; 30467ec681f3Smrg state->info.view_mask = subpass->view_mask; 30477ec681f3Smrg 30487ec681f3Smrg state->pctx->set_patch_vertices(state->pctx, state->patch_vertices); 30497ec681f3Smrg state->pctx->draw_vbo(state->pctx, &state->info, 0, &state->indirect_info, &draw, 1); 30507ec681f3Smrg} 30517ec681f3Smrg 30527ec681f3Smrgstatic void handle_compute_push_descriptor_set(struct lvp_cmd_push_descriptor_set *pds, 30537ec681f3Smrg struct dyn_info *dyn_info, 30547ec681f3Smrg struct rendering_state *state) 30557ec681f3Smrg{ 30567ec681f3Smrg struct lvp_descriptor_set_layout *layout = pds->layout->set[pds->set].layout; 30577ec681f3Smrg 30587ec681f3Smrg if (!(layout->shader_stages & VK_SHADER_STAGE_COMPUTE_BIT)) 30597ec681f3Smrg return; 30607ec681f3Smrg for (unsigned i = 0; i < pds->set; i++) { 30617ec681f3Smrg increment_dyn_info(dyn_info, pds->layout->set[i].layout, false); 30627ec681f3Smrg } 30637ec681f3Smrg unsigned info_idx = 0; 30647ec681f3Smrg for (unsigned i = 0; i < pds->descriptor_write_count; i++) { 30657ec681f3Smrg struct lvp_write_descriptor *desc = &pds->descriptors[i]; 30667ec681f3Smrg struct lvp_descriptor_set_binding_layout *binding = &layout->binding[desc->dst_binding]; 30677ec681f3Smrg 30687ec681f3Smrg if (!binding->valid) 30697ec681f3Smrg continue; 30707ec681f3Smrg 30717ec681f3Smrg for (unsigned j = 0; j < desc->descriptor_count; j++) { 30727ec681f3Smrg union lvp_descriptor_info *info = &pds->infos[info_idx + j]; 30737ec681f3Smrg 30747ec681f3Smrg handle_descriptor(state, dyn_info, binding, 30757ec681f3Smrg MESA_SHADER_COMPUTE, PIPE_SHADER_COMPUTE, 30767ec681f3Smrg j, desc->descriptor_type, 30777ec681f3Smrg info); 30787ec681f3Smrg } 30797ec681f3Smrg info_idx += desc->descriptor_count; 30807ec681f3Smrg } 30817ec681f3Smrg} 30827ec681f3Smrg 30837ec681f3Smrgstatic struct lvp_cmd_push_descriptor_set *create_push_descriptor_set(struct vk_cmd_push_descriptor_set_khr *in_cmd) 30847ec681f3Smrg{ 30857ec681f3Smrg LVP_FROM_HANDLE(lvp_pipeline_layout, layout, in_cmd->layout); 30867ec681f3Smrg struct lvp_cmd_push_descriptor_set *out_cmd; 30877ec681f3Smrg int count_descriptors = 0; 30887ec681f3Smrg int cmd_size = sizeof(*out_cmd); 30897ec681f3Smrg 30907ec681f3Smrg for (unsigned i = 0; i < in_cmd->descriptor_write_count; i++) { 30917ec681f3Smrg count_descriptors += in_cmd->descriptor_writes[i].descriptorCount; 30927ec681f3Smrg } 30937ec681f3Smrg cmd_size += count_descriptors * sizeof(union lvp_descriptor_info); 30947ec681f3Smrg 30957ec681f3Smrg cmd_size += in_cmd->descriptor_write_count * sizeof(struct lvp_write_descriptor); 30967ec681f3Smrg 30977ec681f3Smrg out_cmd = calloc(1, cmd_size); 30987ec681f3Smrg if (!out_cmd) 30997ec681f3Smrg return NULL; 31007ec681f3Smrg 31017ec681f3Smrg out_cmd->bind_point = in_cmd->pipeline_bind_point; 31027ec681f3Smrg out_cmd->layout = layout; 31037ec681f3Smrg out_cmd->set = in_cmd->set; 31047ec681f3Smrg out_cmd->descriptor_write_count = in_cmd->descriptor_write_count; 31057ec681f3Smrg out_cmd->descriptors = (struct lvp_write_descriptor *)(out_cmd + 1); 31067ec681f3Smrg out_cmd->infos = (union lvp_descriptor_info *)(out_cmd->descriptors + in_cmd->descriptor_write_count); 31077ec681f3Smrg 31087ec681f3Smrg unsigned descriptor_index = 0; 31097ec681f3Smrg 31107ec681f3Smrg for (unsigned i = 0; i < in_cmd->descriptor_write_count; i++) { 31117ec681f3Smrg struct lvp_write_descriptor *desc = &out_cmd->descriptors[i]; 31127ec681f3Smrg 31137ec681f3Smrg /* dstSet is ignored */ 31147ec681f3Smrg desc->dst_binding = in_cmd->descriptor_writes[i].dstBinding; 31157ec681f3Smrg desc->dst_array_element = in_cmd->descriptor_writes[i].dstArrayElement; 31167ec681f3Smrg desc->descriptor_count = in_cmd->descriptor_writes[i].descriptorCount; 31177ec681f3Smrg desc->descriptor_type = in_cmd->descriptor_writes[i].descriptorType; 31187ec681f3Smrg 31197ec681f3Smrg for (unsigned j = 0; j < desc->descriptor_count; j++) { 31207ec681f3Smrg union lvp_descriptor_info *info = &out_cmd->infos[descriptor_index + j]; 31217ec681f3Smrg switch (desc->descriptor_type) { 31227ec681f3Smrg case VK_DESCRIPTOR_TYPE_SAMPLER: 31237ec681f3Smrg info->sampler = lvp_sampler_from_handle(in_cmd->descriptor_writes[i].pImageInfo[j].sampler); 31247ec681f3Smrg break; 31257ec681f3Smrg case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 31267ec681f3Smrg info->sampler = lvp_sampler_from_handle(in_cmd->descriptor_writes[i].pImageInfo[j].sampler); 31277ec681f3Smrg info->iview = lvp_image_view_from_handle(in_cmd->descriptor_writes[i].pImageInfo[j].imageView); 31287ec681f3Smrg info->image_layout = in_cmd->descriptor_writes[i].pImageInfo[j].imageLayout; 31297ec681f3Smrg break; 31307ec681f3Smrg case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 31317ec681f3Smrg case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 31327ec681f3Smrg case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 31337ec681f3Smrg info->iview = lvp_image_view_from_handle(in_cmd->descriptor_writes[i].pImageInfo[j].imageView); 31347ec681f3Smrg info->image_layout = in_cmd->descriptor_writes[i].pImageInfo[j].imageLayout; 31357ec681f3Smrg break; 31367ec681f3Smrg case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 31377ec681f3Smrg case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 31387ec681f3Smrg info->buffer_view = lvp_buffer_view_from_handle(in_cmd->descriptor_writes[i].pTexelBufferView[j]); 31397ec681f3Smrg break; 31407ec681f3Smrg case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 31417ec681f3Smrg case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 31427ec681f3Smrg case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 31437ec681f3Smrg case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 31447ec681f3Smrg default: 31457ec681f3Smrg info->buffer = lvp_buffer_from_handle(in_cmd->descriptor_writes[i].pBufferInfo[j].buffer); 31467ec681f3Smrg info->offset = in_cmd->descriptor_writes[i].pBufferInfo[j].offset; 31477ec681f3Smrg info->range = in_cmd->descriptor_writes[i].pBufferInfo[j].range; 31487ec681f3Smrg break; 31497ec681f3Smrg } 31507ec681f3Smrg } 31517ec681f3Smrg descriptor_index += desc->descriptor_count; 31527ec681f3Smrg } 31537ec681f3Smrg 31547ec681f3Smrg return out_cmd; 31557ec681f3Smrg} 31567ec681f3Smrg 31577ec681f3Smrgstatic void handle_push_descriptor_set_generic(struct vk_cmd_push_descriptor_set_khr *_pds, 31587ec681f3Smrg struct rendering_state *state) 31597ec681f3Smrg{ 31607ec681f3Smrg struct lvp_cmd_push_descriptor_set *pds; 31617ec681f3Smrg struct lvp_descriptor_set_layout *layout; 31627ec681f3Smrg struct dyn_info dyn_info; 31637ec681f3Smrg 31647ec681f3Smrg pds = create_push_descriptor_set(_pds); 31657ec681f3Smrg layout = pds->layout->set[pds->set].layout; 31667ec681f3Smrg 31677ec681f3Smrg memset(&dyn_info.stage, 0, sizeof(dyn_info.stage)); 31687ec681f3Smrg dyn_info.dyn_index = 0; 31697ec681f3Smrg if (pds->bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) { 31707ec681f3Smrg handle_compute_push_descriptor_set(pds, &dyn_info, state); 31717ec681f3Smrg } 31727ec681f3Smrg 31737ec681f3Smrg for (unsigned i = 0; i < pds->set; i++) { 31747ec681f3Smrg increment_dyn_info(&dyn_info, pds->layout->set[i].layout, false); 31757ec681f3Smrg } 31767ec681f3Smrg 31777ec681f3Smrg unsigned info_idx = 0; 31787ec681f3Smrg for (unsigned i = 0; i < pds->descriptor_write_count; i++) { 31797ec681f3Smrg struct lvp_write_descriptor *desc = &pds->descriptors[i]; 31807ec681f3Smrg struct lvp_descriptor_set_binding_layout *binding = &layout->binding[desc->dst_binding]; 31817ec681f3Smrg 31827ec681f3Smrg if (!binding->valid) 31837ec681f3Smrg continue; 31847ec681f3Smrg 31857ec681f3Smrg for (unsigned j = 0; j < desc->descriptor_count; j++) { 31867ec681f3Smrg union lvp_descriptor_info *info = &pds->infos[info_idx + j]; 31877ec681f3Smrg 31887ec681f3Smrg if (layout->shader_stages & VK_SHADER_STAGE_VERTEX_BIT) 31897ec681f3Smrg handle_descriptor(state, &dyn_info, binding, 31907ec681f3Smrg MESA_SHADER_VERTEX, PIPE_SHADER_VERTEX, 31917ec681f3Smrg j, desc->descriptor_type, 31927ec681f3Smrg info); 31937ec681f3Smrg if (layout->shader_stages & VK_SHADER_STAGE_FRAGMENT_BIT) 31947ec681f3Smrg handle_descriptor(state, &dyn_info, binding, 31957ec681f3Smrg MESA_SHADER_FRAGMENT, PIPE_SHADER_FRAGMENT, 31967ec681f3Smrg j, desc->descriptor_type, 31977ec681f3Smrg info); 31987ec681f3Smrg if (layout->shader_stages & VK_SHADER_STAGE_GEOMETRY_BIT) 31997ec681f3Smrg handle_descriptor(state, &dyn_info, binding, 32007ec681f3Smrg MESA_SHADER_GEOMETRY, PIPE_SHADER_GEOMETRY, 32017ec681f3Smrg j, desc->descriptor_type, 32027ec681f3Smrg info); 32037ec681f3Smrg if (layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) 32047ec681f3Smrg handle_descriptor(state, &dyn_info, binding, 32057ec681f3Smrg MESA_SHADER_TESS_CTRL, PIPE_SHADER_TESS_CTRL, 32067ec681f3Smrg j, desc->descriptor_type, 32077ec681f3Smrg info); 32087ec681f3Smrg if (layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) 32097ec681f3Smrg handle_descriptor(state, &dyn_info, binding, 32107ec681f3Smrg MESA_SHADER_TESS_EVAL, PIPE_SHADER_TESS_EVAL, 32117ec681f3Smrg j, desc->descriptor_type, 32127ec681f3Smrg info); 32137ec681f3Smrg } 32147ec681f3Smrg info_idx += desc->descriptor_count; 32157ec681f3Smrg } 32167ec681f3Smrg free(pds); 32177ec681f3Smrg} 32187ec681f3Smrg 32197ec681f3Smrgstatic void handle_push_descriptor_set(struct vk_cmd_queue_entry *cmd, 32207ec681f3Smrg struct rendering_state *state) 32217ec681f3Smrg{ 32227ec681f3Smrg handle_push_descriptor_set_generic(&cmd->u.push_descriptor_set_khr, state); 32237ec681f3Smrg} 32247ec681f3Smrg 32257ec681f3Smrgstatic void handle_push_descriptor_set_with_template(struct vk_cmd_queue_entry *cmd, 32267ec681f3Smrg struct rendering_state *state) 32277ec681f3Smrg{ 32287ec681f3Smrg LVP_FROM_HANDLE(lvp_descriptor_update_template, templ, cmd->u.push_descriptor_set_with_template_khr.descriptor_update_template); 32297ec681f3Smrg struct vk_cmd_push_descriptor_set_khr *pds; 32307ec681f3Smrg int pds_size = sizeof(*pds); 32317ec681f3Smrg 32327ec681f3Smrg pds_size += templ->entry_count * sizeof(struct VkWriteDescriptorSet); 32337ec681f3Smrg 32347ec681f3Smrg for (unsigned i = 0; i < templ->entry_count; i++) { 32357ec681f3Smrg VkDescriptorUpdateTemplateEntry *entry = &templ->entry[i]; 32367ec681f3Smrg switch (entry->descriptorType) { 32377ec681f3Smrg case VK_DESCRIPTOR_TYPE_SAMPLER: 32387ec681f3Smrg case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 32397ec681f3Smrg case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 32407ec681f3Smrg case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 32417ec681f3Smrg case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 32427ec681f3Smrg pds_size += sizeof(VkDescriptorImageInfo) * entry->descriptorCount; 32437ec681f3Smrg break; 32447ec681f3Smrg case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 32457ec681f3Smrg case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 32467ec681f3Smrg pds_size += sizeof(VkBufferView) * entry->descriptorCount; 32477ec681f3Smrg break; 32487ec681f3Smrg case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 32497ec681f3Smrg case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 32507ec681f3Smrg case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 32517ec681f3Smrg case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 32527ec681f3Smrg default: 32537ec681f3Smrg pds_size += sizeof(VkDescriptorBufferInfo) * entry->descriptorCount; 32547ec681f3Smrg break; 32557ec681f3Smrg } 32567ec681f3Smrg } 32577ec681f3Smrg 32587ec681f3Smrg pds = calloc(1, pds_size); 32597ec681f3Smrg if (!pds) 32607ec681f3Smrg return; 32617ec681f3Smrg 32627ec681f3Smrg pds->pipeline_bind_point = templ->bind_point; 32637ec681f3Smrg pds->layout = lvp_pipeline_layout_to_handle(templ->pipeline_layout); 32647ec681f3Smrg pds->set = templ->set; 32657ec681f3Smrg pds->descriptor_write_count = templ->entry_count; 32667ec681f3Smrg pds->descriptor_writes = (struct VkWriteDescriptorSet *)(pds + 1); 32677ec681f3Smrg const uint8_t *next_info = (const uint8_t *) (pds->descriptor_writes + templ->entry_count); 32687ec681f3Smrg 32697ec681f3Smrg const uint8_t *pSrc = cmd->u.push_descriptor_set_with_template_khr.data; 32707ec681f3Smrg for (unsigned i = 0; i < templ->entry_count; i++) { 32717ec681f3Smrg struct VkWriteDescriptorSet *desc = &pds->descriptor_writes[i]; 32727ec681f3Smrg struct VkDescriptorUpdateTemplateEntry *entry = &templ->entry[i]; 32737ec681f3Smrg 32747ec681f3Smrg /* dstSet is ignored */ 32757ec681f3Smrg desc->dstBinding = entry->dstBinding; 32767ec681f3Smrg desc->dstArrayElement = entry->dstArrayElement; 32777ec681f3Smrg desc->descriptorCount = entry->descriptorCount; 32787ec681f3Smrg desc->descriptorType = entry->descriptorType; 32797ec681f3Smrg desc->pImageInfo = (const VkDescriptorImageInfo *) next_info; 32807ec681f3Smrg desc->pTexelBufferView = (const VkBufferView *) next_info; 32817ec681f3Smrg desc->pBufferInfo = (const VkDescriptorBufferInfo *) next_info; 32827ec681f3Smrg 32837ec681f3Smrg for (unsigned j = 0; j < desc->descriptorCount; j++) { 32847ec681f3Smrg switch (desc->descriptorType) { 32857ec681f3Smrg case VK_DESCRIPTOR_TYPE_SAMPLER: 32867ec681f3Smrg case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 32877ec681f3Smrg case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 32887ec681f3Smrg case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 32897ec681f3Smrg case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 32907ec681f3Smrg memcpy((VkDescriptorImageInfo*)&desc->pImageInfo[j], pSrc, sizeof(VkDescriptorImageInfo)); 32917ec681f3Smrg next_info += sizeof(VkDescriptorImageInfo); 32927ec681f3Smrg pSrc += sizeof(VkDescriptorImageInfo); 32937ec681f3Smrg break; 32947ec681f3Smrg case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 32957ec681f3Smrg case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 32967ec681f3Smrg memcpy((VkBufferView*)&desc->pTexelBufferView[j], pSrc, sizeof(VkBufferView)); 32977ec681f3Smrg next_info += sizeof(VkBufferView); 32987ec681f3Smrg pSrc += sizeof(VkBufferView); 32997ec681f3Smrg break; 33007ec681f3Smrg case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 33017ec681f3Smrg case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 33027ec681f3Smrg case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 33037ec681f3Smrg case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 33047ec681f3Smrg default: 33057ec681f3Smrg memcpy((VkDescriptorBufferInfo*)&desc->pBufferInfo[j], pSrc, sizeof(VkDescriptorBufferInfo)); 33067ec681f3Smrg next_info += sizeof(VkDescriptorBufferInfo); 33077ec681f3Smrg pSrc += sizeof(VkDescriptorBufferInfo); 33087ec681f3Smrg break; 33097ec681f3Smrg } 33107ec681f3Smrg } 33117ec681f3Smrg } 33127ec681f3Smrg handle_push_descriptor_set_generic(pds, state); 33137ec681f3Smrg free(pds); 33147ec681f3Smrg} 33157ec681f3Smrg 33167ec681f3Smrgstatic void handle_bind_transform_feedback_buffers(struct vk_cmd_queue_entry *cmd, 33177ec681f3Smrg struct rendering_state *state) 33187ec681f3Smrg{ 33197ec681f3Smrg struct vk_cmd_bind_transform_feedback_buffers_ext *btfb = &cmd->u.bind_transform_feedback_buffers_ext; 33207ec681f3Smrg 33217ec681f3Smrg for (unsigned i = 0; i < btfb->binding_count; i++) { 33227ec681f3Smrg int idx = i + btfb->first_binding; 33237ec681f3Smrg uint32_t size; 33247ec681f3Smrg if (btfb->sizes && btfb->sizes[i] != VK_WHOLE_SIZE) 33257ec681f3Smrg size = btfb->sizes[i]; 33267ec681f3Smrg else 33277ec681f3Smrg size = lvp_buffer_from_handle(btfb->buffers[i])->size - btfb->offsets[i]; 33287ec681f3Smrg 33297ec681f3Smrg if (state->so_targets[idx]) 33307ec681f3Smrg state->pctx->stream_output_target_destroy(state->pctx, state->so_targets[idx]); 33317ec681f3Smrg 33327ec681f3Smrg state->so_targets[idx] = state->pctx->create_stream_output_target(state->pctx, 33337ec681f3Smrg lvp_buffer_from_handle(btfb->buffers[i])->bo, 33347ec681f3Smrg btfb->offsets[i], 33357ec681f3Smrg size); 33367ec681f3Smrg } 33377ec681f3Smrg state->num_so_targets = btfb->first_binding + btfb->binding_count; 33387ec681f3Smrg} 33397ec681f3Smrg 33407ec681f3Smrgstatic void handle_begin_transform_feedback(struct vk_cmd_queue_entry *cmd, 33417ec681f3Smrg struct rendering_state *state) 33427ec681f3Smrg{ 33437ec681f3Smrg struct vk_cmd_begin_transform_feedback_ext *btf = &cmd->u.begin_transform_feedback_ext; 33447ec681f3Smrg uint32_t offsets[4]; 33457ec681f3Smrg 33467ec681f3Smrg memset(offsets, 0, sizeof(uint32_t)*4); 33477ec681f3Smrg 33487ec681f3Smrg for (unsigned i = 0; i < btf->counter_buffer_count; i++) { 33497ec681f3Smrg if (!btf->counter_buffers[i]) 33507ec681f3Smrg continue; 33517ec681f3Smrg 33527ec681f3Smrg pipe_buffer_read(state->pctx, 33537ec681f3Smrg btf->counter_buffers ? lvp_buffer_from_handle(btf->counter_buffers[i])->bo : NULL, 33547ec681f3Smrg btf->counter_buffer_offsets ? btf->counter_buffer_offsets[i] : 0, 33557ec681f3Smrg 4, 33567ec681f3Smrg &offsets[i]); 33577ec681f3Smrg } 33587ec681f3Smrg state->pctx->set_stream_output_targets(state->pctx, state->num_so_targets, 33597ec681f3Smrg state->so_targets, offsets); 33607ec681f3Smrg} 33617ec681f3Smrg 33627ec681f3Smrgstatic void handle_end_transform_feedback(struct vk_cmd_queue_entry *cmd, 33637ec681f3Smrg struct rendering_state *state) 33647ec681f3Smrg{ 33657ec681f3Smrg struct vk_cmd_end_transform_feedback_ext *etf = &cmd->u.end_transform_feedback_ext; 33667ec681f3Smrg 33677ec681f3Smrg if (etf->counter_buffer_count) { 33687ec681f3Smrg for (unsigned i = 0; i < etf->counter_buffer_count; i++) { 33697ec681f3Smrg if (!etf->counter_buffers[i]) 33707ec681f3Smrg continue; 33717ec681f3Smrg 33727ec681f3Smrg uint32_t offset; 33737ec681f3Smrg offset = state->pctx->stream_output_target_offset(state->so_targets[i]); 33747ec681f3Smrg 33757ec681f3Smrg pipe_buffer_write(state->pctx, 33767ec681f3Smrg etf->counter_buffers ? lvp_buffer_from_handle(etf->counter_buffers[i])->bo : NULL, 33777ec681f3Smrg etf->counter_buffer_offsets ? etf->counter_buffer_offsets[i] : 0, 33787ec681f3Smrg 4, 33797ec681f3Smrg &offset); 33807ec681f3Smrg } 33817ec681f3Smrg } 33827ec681f3Smrg state->pctx->set_stream_output_targets(state->pctx, 0, NULL, NULL); 33837ec681f3Smrg} 33847ec681f3Smrg 33857ec681f3Smrgstatic void handle_draw_indirect_byte_count(struct vk_cmd_queue_entry *cmd, 33867ec681f3Smrg struct rendering_state *state) 33877ec681f3Smrg{ 33887ec681f3Smrg struct vk_cmd_draw_indirect_byte_count_ext *dibc = &cmd->u.draw_indirect_byte_count_ext; 33897ec681f3Smrg const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass]; 33907ec681f3Smrg struct pipe_draw_start_count_bias draw = {0}; 33917ec681f3Smrg 33927ec681f3Smrg pipe_buffer_read(state->pctx, 33937ec681f3Smrg lvp_buffer_from_handle(dibc->counter_buffer)->bo, 33947ec681f3Smrg lvp_buffer_from_handle(dibc->counter_buffer)->offset + dibc->counter_buffer_offset, 33957ec681f3Smrg 4, &draw.count); 33967ec681f3Smrg 33977ec681f3Smrg state->info.start_instance = cmd->u.draw_indirect_byte_count_ext.first_instance; 33987ec681f3Smrg state->info.instance_count = cmd->u.draw_indirect_byte_count_ext.instance_count; 33997ec681f3Smrg state->info.index_size = 0; 34007ec681f3Smrg 34017ec681f3Smrg draw.count /= cmd->u.draw_indirect_byte_count_ext.vertex_stride; 34027ec681f3Smrg state->info.view_mask = subpass->view_mask; 34037ec681f3Smrg state->pctx->set_patch_vertices(state->pctx, state->patch_vertices); 34047ec681f3Smrg state->pctx->draw_vbo(state->pctx, &state->info, 0, &state->indirect_info, &draw, 1); 34057ec681f3Smrg} 34067ec681f3Smrg 34077ec681f3Smrgstatic void handle_begin_conditional_rendering(struct vk_cmd_queue_entry *cmd, 34087ec681f3Smrg struct rendering_state *state) 34097ec681f3Smrg{ 34107ec681f3Smrg struct VkConditionalRenderingBeginInfoEXT *bcr = cmd->u.begin_conditional_rendering_ext.conditional_rendering_begin; 34117ec681f3Smrg state->pctx->render_condition_mem(state->pctx, 34127ec681f3Smrg lvp_buffer_from_handle(bcr->buffer)->bo, 34137ec681f3Smrg lvp_buffer_from_handle(bcr->buffer)->offset + bcr->offset, 34147ec681f3Smrg bcr->flags & VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT); 34157ec681f3Smrg} 34167ec681f3Smrg 34177ec681f3Smrgstatic void handle_end_conditional_rendering(struct rendering_state *state) 34187ec681f3Smrg{ 34197ec681f3Smrg state->pctx->render_condition_mem(state->pctx, NULL, 0, false); 34207ec681f3Smrg} 34217ec681f3Smrg 34227ec681f3Smrgstatic void handle_set_vertex_input(struct vk_cmd_queue_entry *cmd, 34237ec681f3Smrg struct rendering_state *state) 34247ec681f3Smrg{ 34257ec681f3Smrg const struct vk_cmd_set_vertex_input_ext *vertex_input = &cmd->u.set_vertex_input_ext; 34267ec681f3Smrg const struct VkVertexInputBindingDescription2EXT *bindings = vertex_input->vertex_binding_descriptions; 34277ec681f3Smrg const struct VkVertexInputAttributeDescription2EXT *attrs = vertex_input->vertex_attribute_descriptions; 34287ec681f3Smrg int max_location = -1; 34297ec681f3Smrg for (unsigned i = 0; i < vertex_input->vertex_attribute_description_count; i++) { 34307ec681f3Smrg const struct VkVertexInputBindingDescription2EXT *binding = NULL; 34317ec681f3Smrg unsigned location = attrs[i].location; 34327ec681f3Smrg 34337ec681f3Smrg for (unsigned j = 0; j < vertex_input->vertex_binding_description_count; j++) { 34347ec681f3Smrg const struct VkVertexInputBindingDescription2EXT *b = &bindings[j]; 34357ec681f3Smrg if (b->binding == attrs[i].binding) { 34367ec681f3Smrg binding = b; 34377ec681f3Smrg break; 34387ec681f3Smrg } 34397ec681f3Smrg } 34407ec681f3Smrg assert(binding); 34417ec681f3Smrg state->velem.velems[location].src_offset = attrs[i].offset; 34427ec681f3Smrg state->velem.velems[location].vertex_buffer_index = attrs[i].binding; 34437ec681f3Smrg state->velem.velems[location].src_format = lvp_vk_format_to_pipe_format(attrs[i].format); 34447ec681f3Smrg state->vb[attrs[i].binding].stride = binding->stride; 34457ec681f3Smrg 34467ec681f3Smrg switch (binding->inputRate) { 34477ec681f3Smrg case VK_VERTEX_INPUT_RATE_VERTEX: 34487ec681f3Smrg state->velem.velems[location].instance_divisor = 0; 34497ec681f3Smrg break; 34507ec681f3Smrg case VK_VERTEX_INPUT_RATE_INSTANCE: 34517ec681f3Smrg state->velem.velems[location].instance_divisor = binding->divisor; 34527ec681f3Smrg break; 34537ec681f3Smrg default: 34547ec681f3Smrg assert(0); 34557ec681f3Smrg break; 34567ec681f3Smrg } 34577ec681f3Smrg 34587ec681f3Smrg if ((int)location > max_location) 34597ec681f3Smrg max_location = location; 34607ec681f3Smrg } 34617ec681f3Smrg state->velem.count = max_location + 1; 34627ec681f3Smrg state->vb_dirty = true; 34637ec681f3Smrg state->ve_dirty = true; 34647ec681f3Smrg} 34657ec681f3Smrg 34667ec681f3Smrgstatic void handle_set_cull_mode(struct vk_cmd_queue_entry *cmd, 34677ec681f3Smrg struct rendering_state *state) 34687ec681f3Smrg{ 34697ec681f3Smrg state->rs_state.cull_face = vk_cull_to_pipe(cmd->u.set_cull_mode_ext.cull_mode); 34707ec681f3Smrg state->rs_dirty = true; 34717ec681f3Smrg} 34727ec681f3Smrg 34737ec681f3Smrgstatic void handle_set_front_face(struct vk_cmd_queue_entry *cmd, 34747ec681f3Smrg struct rendering_state *state) 34757ec681f3Smrg{ 34767ec681f3Smrg state->rs_state.front_ccw = (cmd->u.set_front_face_ext.front_face == VK_FRONT_FACE_COUNTER_CLOCKWISE); 34777ec681f3Smrg state->rs_dirty = true; 34787ec681f3Smrg} 34797ec681f3Smrg 34807ec681f3Smrgstatic void handle_set_primitive_topology(struct vk_cmd_queue_entry *cmd, 34817ec681f3Smrg struct rendering_state *state) 34827ec681f3Smrg{ 34837ec681f3Smrg state->info.mode = vk_conv_topology(cmd->u.set_primitive_topology_ext.primitive_topology); 34847ec681f3Smrg state->rs_dirty = true; 34857ec681f3Smrg} 34867ec681f3Smrg 34877ec681f3Smrg 34887ec681f3Smrgstatic void handle_set_depth_test_enable(struct vk_cmd_queue_entry *cmd, 34897ec681f3Smrg struct rendering_state *state) 34907ec681f3Smrg{ 34917ec681f3Smrg state->dsa_dirty |= state->dsa_state.depth_enabled != cmd->u.set_depth_test_enable_ext.depth_test_enable; 34927ec681f3Smrg state->dsa_state.depth_enabled = cmd->u.set_depth_test_enable_ext.depth_test_enable; 34937ec681f3Smrg} 34947ec681f3Smrg 34957ec681f3Smrgstatic void handle_set_depth_write_enable(struct vk_cmd_queue_entry *cmd, 34967ec681f3Smrg struct rendering_state *state) 34977ec681f3Smrg{ 34987ec681f3Smrg state->dsa_dirty |= state->dsa_state.depth_writemask != cmd->u.set_depth_write_enable_ext.depth_write_enable; 34997ec681f3Smrg state->dsa_state.depth_writemask = cmd->u.set_depth_write_enable_ext.depth_write_enable; 35007ec681f3Smrg} 35017ec681f3Smrg 35027ec681f3Smrgstatic void handle_set_depth_compare_op(struct vk_cmd_queue_entry *cmd, 35037ec681f3Smrg struct rendering_state *state) 35047ec681f3Smrg{ 35057ec681f3Smrg state->dsa_dirty |= state->dsa_state.depth_func != cmd->u.set_depth_compare_op_ext.depth_compare_op; 35067ec681f3Smrg state->dsa_state.depth_func = cmd->u.set_depth_compare_op_ext.depth_compare_op; 35077ec681f3Smrg} 35087ec681f3Smrg 35097ec681f3Smrgstatic void handle_set_depth_bounds_test_enable(struct vk_cmd_queue_entry *cmd, 35107ec681f3Smrg struct rendering_state *state) 35117ec681f3Smrg{ 35127ec681f3Smrg state->dsa_dirty |= state->dsa_state.depth_bounds_test != cmd->u.set_depth_bounds_test_enable_ext.depth_bounds_test_enable; 35137ec681f3Smrg state->dsa_state.depth_bounds_test = cmd->u.set_depth_bounds_test_enable_ext.depth_bounds_test_enable; 35147ec681f3Smrg} 35157ec681f3Smrg 35167ec681f3Smrgstatic void handle_set_stencil_test_enable(struct vk_cmd_queue_entry *cmd, 35177ec681f3Smrg struct rendering_state *state) 35187ec681f3Smrg{ 35197ec681f3Smrg state->dsa_dirty |= state->dsa_state.stencil[0].enabled != cmd->u.set_stencil_test_enable_ext.stencil_test_enable || 35207ec681f3Smrg state->dsa_state.stencil[1].enabled != cmd->u.set_stencil_test_enable_ext.stencil_test_enable; 35217ec681f3Smrg state->dsa_state.stencil[0].enabled = cmd->u.set_stencil_test_enable_ext.stencil_test_enable; 35227ec681f3Smrg state->dsa_state.stencil[1].enabled = cmd->u.set_stencil_test_enable_ext.stencil_test_enable; 35237ec681f3Smrg} 35247ec681f3Smrg 35257ec681f3Smrgstatic void handle_set_stencil_op(struct vk_cmd_queue_entry *cmd, 35267ec681f3Smrg struct rendering_state *state) 35277ec681f3Smrg{ 35287ec681f3Smrg if (cmd->u.set_stencil_op_ext.face_mask & VK_STENCIL_FACE_FRONT_BIT) { 35297ec681f3Smrg state->dsa_state.stencil[0].func = cmd->u.set_stencil_op_ext.compare_op; 35307ec681f3Smrg state->dsa_state.stencil[0].fail_op = vk_conv_stencil_op(cmd->u.set_stencil_op_ext.fail_op); 35317ec681f3Smrg state->dsa_state.stencil[0].zpass_op = vk_conv_stencil_op(cmd->u.set_stencil_op_ext.pass_op); 35327ec681f3Smrg state->dsa_state.stencil[0].zfail_op = vk_conv_stencil_op(cmd->u.set_stencil_op_ext.depth_fail_op); 35337ec681f3Smrg } 35347ec681f3Smrg 35357ec681f3Smrg if (cmd->u.set_stencil_op_ext.face_mask & VK_STENCIL_FACE_BACK_BIT) { 35367ec681f3Smrg state->dsa_state.stencil[1].func = cmd->u.set_stencil_op_ext.compare_op; 35377ec681f3Smrg state->dsa_state.stencil[1].fail_op = vk_conv_stencil_op(cmd->u.set_stencil_op_ext.fail_op); 35387ec681f3Smrg state->dsa_state.stencil[1].zpass_op = vk_conv_stencil_op(cmd->u.set_stencil_op_ext.pass_op); 35397ec681f3Smrg state->dsa_state.stencil[1].zfail_op = vk_conv_stencil_op(cmd->u.set_stencil_op_ext.depth_fail_op); 35407ec681f3Smrg } 35417ec681f3Smrg state->dsa_dirty = true; 35427ec681f3Smrg} 35437ec681f3Smrg 35447ec681f3Smrgstatic void handle_set_line_stipple(struct vk_cmd_queue_entry *cmd, 35457ec681f3Smrg struct rendering_state *state) 35467ec681f3Smrg{ 35477ec681f3Smrg state->rs_state.line_stipple_factor = cmd->u.set_line_stipple_ext.line_stipple_factor - 1; 35487ec681f3Smrg state->rs_state.line_stipple_pattern = cmd->u.set_line_stipple_ext.line_stipple_pattern; 35497ec681f3Smrg state->rs_dirty = true; 35507ec681f3Smrg} 35517ec681f3Smrg 35527ec681f3Smrgstatic void handle_set_depth_bias_enable(struct vk_cmd_queue_entry *cmd, 35537ec681f3Smrg struct rendering_state *state) 35547ec681f3Smrg{ 35557ec681f3Smrg state->rs_dirty |= state->depth_bias.enabled != cmd->u.set_depth_bias_enable_ext.depth_bias_enable; 35567ec681f3Smrg state->depth_bias.enabled = cmd->u.set_depth_bias_enable_ext.depth_bias_enable; 35577ec681f3Smrg} 35587ec681f3Smrg 35597ec681f3Smrgstatic void handle_set_logic_op(struct vk_cmd_queue_entry *cmd, 35607ec681f3Smrg struct rendering_state *state) 35617ec681f3Smrg{ 35627ec681f3Smrg unsigned op = vk_conv_logic_op(cmd->u.set_logic_op_ext.logic_op); 35637ec681f3Smrg state->rs_dirty |= state->blend_state.logicop_func != op; 35647ec681f3Smrg state->blend_state.logicop_func = op; 35657ec681f3Smrg} 35667ec681f3Smrg 35677ec681f3Smrgstatic void handle_set_patch_control_points(struct vk_cmd_queue_entry *cmd, 35687ec681f3Smrg struct rendering_state *state) 35697ec681f3Smrg{ 35707ec681f3Smrg state->patch_vertices = cmd->u.set_patch_control_points_ext.patch_control_points; 35717ec681f3Smrg} 35727ec681f3Smrg 35737ec681f3Smrgstatic void handle_set_primitive_restart_enable(struct vk_cmd_queue_entry *cmd, 35747ec681f3Smrg struct rendering_state *state) 35757ec681f3Smrg{ 35767ec681f3Smrg state->info.primitive_restart = cmd->u.set_primitive_restart_enable_ext.primitive_restart_enable; 35777ec681f3Smrg} 35787ec681f3Smrg 35797ec681f3Smrgstatic void handle_set_rasterizer_discard_enable(struct vk_cmd_queue_entry *cmd, 35807ec681f3Smrg struct rendering_state *state) 35817ec681f3Smrg{ 35827ec681f3Smrg state->rs_dirty |= state->rs_state.rasterizer_discard != cmd->u.set_rasterizer_discard_enable_ext.rasterizer_discard_enable; 35837ec681f3Smrg state->rs_state.rasterizer_discard = cmd->u.set_rasterizer_discard_enable_ext.rasterizer_discard_enable; 35847ec681f3Smrg} 35857ec681f3Smrg 35867ec681f3Smrgstatic void handle_set_color_write_enable(struct vk_cmd_queue_entry *cmd, 35877ec681f3Smrg struct rendering_state *state) 35887ec681f3Smrg{ 35897ec681f3Smrg uint8_t disable_mask = 0; //PIPE_MAX_COLOR_BUFS is max attachment count 35907ec681f3Smrg 35917ec681f3Smrg for (unsigned i = 0; i < cmd->u.set_color_write_enable_ext.attachment_count; i++) { 35927ec681f3Smrg /* this is inverted because cmdbufs are zero-initialized, meaning only 'true' 35937ec681f3Smrg * can be detected with a bool, and the default is to enable color writes 35947ec681f3Smrg */ 35957ec681f3Smrg if (cmd->u.set_color_write_enable_ext.color_write_enables[i] != VK_TRUE) 35967ec681f3Smrg disable_mask |= BITFIELD_BIT(i); 35977ec681f3Smrg } 35987ec681f3Smrg 35997ec681f3Smrg state->blend_dirty |= state->color_write_disables != disable_mask; 36007ec681f3Smrg state->color_write_disables = disable_mask; 36017ec681f3Smrg} 36027ec681f3Smrg 36037ec681f3Smrgstatic void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer, 36047ec681f3Smrg struct rendering_state *state) 36057ec681f3Smrg{ 36067ec681f3Smrg struct vk_cmd_queue_entry *cmd; 36077ec681f3Smrg bool first = true; 36087ec681f3Smrg bool did_flush = false; 36097ec681f3Smrg 36107ec681f3Smrg LIST_FOR_EACH_ENTRY(cmd, &cmd_buffer->queue.cmds, cmd_link) { 36117ec681f3Smrg switch (cmd->type) { 36127ec681f3Smrg case VK_CMD_BIND_PIPELINE: 36137ec681f3Smrg handle_pipeline(cmd, state); 36147ec681f3Smrg break; 36157ec681f3Smrg case VK_CMD_SET_VIEWPORT: 36167ec681f3Smrg handle_set_viewport(cmd, state); 36177ec681f3Smrg break; 36187ec681f3Smrg case VK_CMD_SET_VIEWPORT_WITH_COUNT_EXT: 36197ec681f3Smrg handle_set_viewport_with_count(cmd, state); 36207ec681f3Smrg break; 36217ec681f3Smrg case VK_CMD_SET_SCISSOR: 36227ec681f3Smrg handle_set_scissor(cmd, state); 36237ec681f3Smrg break; 36247ec681f3Smrg case VK_CMD_SET_SCISSOR_WITH_COUNT_EXT: 36257ec681f3Smrg handle_set_scissor_with_count(cmd, state); 36267ec681f3Smrg break; 36277ec681f3Smrg case VK_CMD_SET_LINE_WIDTH: 36287ec681f3Smrg handle_set_line_width(cmd, state); 36297ec681f3Smrg break; 36307ec681f3Smrg case VK_CMD_SET_DEPTH_BIAS: 36317ec681f3Smrg handle_set_depth_bias(cmd, state); 36327ec681f3Smrg break; 36337ec681f3Smrg case VK_CMD_SET_BLEND_CONSTANTS: 36347ec681f3Smrg handle_set_blend_constants(cmd, state); 36357ec681f3Smrg break; 36367ec681f3Smrg case VK_CMD_SET_DEPTH_BOUNDS: 36377ec681f3Smrg handle_set_depth_bounds(cmd, state); 36387ec681f3Smrg break; 36397ec681f3Smrg case VK_CMD_SET_STENCIL_COMPARE_MASK: 36407ec681f3Smrg handle_set_stencil_compare_mask(cmd, state); 36417ec681f3Smrg break; 36427ec681f3Smrg case VK_CMD_SET_STENCIL_WRITE_MASK: 36437ec681f3Smrg handle_set_stencil_write_mask(cmd, state); 36447ec681f3Smrg break; 36457ec681f3Smrg case VK_CMD_SET_STENCIL_REFERENCE: 36467ec681f3Smrg handle_set_stencil_reference(cmd, state); 36477ec681f3Smrg break; 36487ec681f3Smrg case VK_CMD_BIND_DESCRIPTOR_SETS: 36497ec681f3Smrg handle_descriptor_sets(cmd, state); 36507ec681f3Smrg break; 36517ec681f3Smrg case VK_CMD_BIND_INDEX_BUFFER: 36527ec681f3Smrg handle_index_buffer(cmd, state); 36537ec681f3Smrg break; 36547ec681f3Smrg case VK_CMD_BIND_VERTEX_BUFFERS: 36557ec681f3Smrg handle_vertex_buffers(cmd, state); 36567ec681f3Smrg break; 36577ec681f3Smrg case VK_CMD_BIND_VERTEX_BUFFERS2_EXT: 36587ec681f3Smrg handle_vertex_buffers2(cmd, state); 36597ec681f3Smrg break; 36607ec681f3Smrg case VK_CMD_DRAW: 36617ec681f3Smrg emit_state(state); 36627ec681f3Smrg handle_draw(cmd, state); 36637ec681f3Smrg break; 36647ec681f3Smrg case VK_CMD_DRAW_MULTI_EXT: 36657ec681f3Smrg emit_state(state); 36667ec681f3Smrg handle_draw_multi(cmd, state); 36677ec681f3Smrg break; 36687ec681f3Smrg case VK_CMD_DRAW_INDEXED: 36697ec681f3Smrg emit_state(state); 36707ec681f3Smrg handle_draw_indexed(cmd, state); 36717ec681f3Smrg break; 36727ec681f3Smrg case VK_CMD_DRAW_INDIRECT: 36737ec681f3Smrg emit_state(state); 36747ec681f3Smrg handle_draw_indirect(cmd, state, false); 36757ec681f3Smrg break; 36767ec681f3Smrg case VK_CMD_DRAW_INDEXED_INDIRECT: 36777ec681f3Smrg emit_state(state); 36787ec681f3Smrg handle_draw_indirect(cmd, state, true); 36797ec681f3Smrg break; 36807ec681f3Smrg case VK_CMD_DRAW_MULTI_INDEXED_EXT: 36817ec681f3Smrg emit_state(state); 36827ec681f3Smrg handle_draw_multi_indexed(cmd, state); 36837ec681f3Smrg break; 36847ec681f3Smrg case VK_CMD_DISPATCH: 36857ec681f3Smrg emit_compute_state(state); 36867ec681f3Smrg handle_dispatch(cmd, state); 36877ec681f3Smrg break; 36887ec681f3Smrg case VK_CMD_DISPATCH_BASE: 36897ec681f3Smrg emit_compute_state(state); 36907ec681f3Smrg handle_dispatch_base(cmd, state); 36917ec681f3Smrg break; 36927ec681f3Smrg case VK_CMD_DISPATCH_INDIRECT: 36937ec681f3Smrg emit_compute_state(state); 36947ec681f3Smrg handle_dispatch_indirect(cmd, state); 36957ec681f3Smrg break; 36967ec681f3Smrg case VK_CMD_COPY_BUFFER2_KHR: 36977ec681f3Smrg handle_copy_buffer(cmd, state); 36987ec681f3Smrg break; 36997ec681f3Smrg case VK_CMD_COPY_IMAGE2_KHR: 37007ec681f3Smrg handle_copy_image(cmd, state); 37017ec681f3Smrg break; 37027ec681f3Smrg case VK_CMD_BLIT_IMAGE2_KHR: 37037ec681f3Smrg handle_blit_image(cmd, state); 37047ec681f3Smrg break; 37057ec681f3Smrg case VK_CMD_COPY_BUFFER_TO_IMAGE2_KHR: 37067ec681f3Smrg handle_copy_buffer_to_image(cmd, state); 37077ec681f3Smrg break; 37087ec681f3Smrg case VK_CMD_COPY_IMAGE_TO_BUFFER2_KHR: 37097ec681f3Smrg handle_copy_image_to_buffer2_khr(cmd, state); 37107ec681f3Smrg break; 37117ec681f3Smrg case VK_CMD_UPDATE_BUFFER: 37127ec681f3Smrg handle_update_buffer(cmd, state); 37137ec681f3Smrg break; 37147ec681f3Smrg case VK_CMD_FILL_BUFFER: 37157ec681f3Smrg handle_fill_buffer(cmd, state); 37167ec681f3Smrg break; 37177ec681f3Smrg case VK_CMD_CLEAR_COLOR_IMAGE: 37187ec681f3Smrg handle_clear_color_image(cmd, state); 37197ec681f3Smrg break; 37207ec681f3Smrg case VK_CMD_CLEAR_DEPTH_STENCIL_IMAGE: 37217ec681f3Smrg handle_clear_ds_image(cmd, state); 37227ec681f3Smrg break; 37237ec681f3Smrg case VK_CMD_CLEAR_ATTACHMENTS: 37247ec681f3Smrg handle_clear_attachments(cmd, state); 37257ec681f3Smrg break; 37267ec681f3Smrg case VK_CMD_RESOLVE_IMAGE2_KHR: 37277ec681f3Smrg handle_resolve_image(cmd, state); 37287ec681f3Smrg break; 37297ec681f3Smrg case VK_CMD_SET_EVENT: 37307ec681f3Smrg handle_event_set(cmd, state); 37317ec681f3Smrg break; 37327ec681f3Smrg case VK_CMD_RESET_EVENT: 37337ec681f3Smrg handle_event_reset(cmd, state); 37347ec681f3Smrg break; 37357ec681f3Smrg case VK_CMD_WAIT_EVENTS: 37367ec681f3Smrg handle_wait_events(cmd, state); 37377ec681f3Smrg break; 37387ec681f3Smrg case VK_CMD_PIPELINE_BARRIER: 37397ec681f3Smrg /* skip flushes since every cmdbuf does a flush 37407ec681f3Smrg after iterating its cmds and so this is redundant 37417ec681f3Smrg */ 37427ec681f3Smrg if (first || did_flush || cmd->cmd_link.next == &cmd_buffer->queue.cmds) 37437ec681f3Smrg continue; 37447ec681f3Smrg handle_pipeline_barrier(cmd, state); 37457ec681f3Smrg did_flush = true; 37467ec681f3Smrg continue; 37477ec681f3Smrg case VK_CMD_BEGIN_QUERY_INDEXED_EXT: 37487ec681f3Smrg handle_begin_query_indexed_ext(cmd, state); 37497ec681f3Smrg break; 37507ec681f3Smrg case VK_CMD_END_QUERY_INDEXED_EXT: 37517ec681f3Smrg handle_end_query_indexed_ext(cmd, state); 37527ec681f3Smrg break; 37537ec681f3Smrg case VK_CMD_BEGIN_QUERY: 37547ec681f3Smrg handle_begin_query(cmd, state); 37557ec681f3Smrg break; 37567ec681f3Smrg case VK_CMD_END_QUERY: 37577ec681f3Smrg handle_end_query(cmd, state); 37587ec681f3Smrg break; 37597ec681f3Smrg case VK_CMD_RESET_QUERY_POOL: 37607ec681f3Smrg handle_reset_query_pool(cmd, state); 37617ec681f3Smrg break; 37627ec681f3Smrg case VK_CMD_WRITE_TIMESTAMP: 37637ec681f3Smrg handle_write_timestamp(cmd, state); 37647ec681f3Smrg break; 37657ec681f3Smrg case VK_CMD_COPY_QUERY_POOL_RESULTS: 37667ec681f3Smrg handle_copy_query_pool_results(cmd, state); 37677ec681f3Smrg break; 37687ec681f3Smrg case VK_CMD_PUSH_CONSTANTS: 37697ec681f3Smrg handle_push_constants(cmd, state); 37707ec681f3Smrg break; 37717ec681f3Smrg case VK_CMD_BEGIN_RENDER_PASS: 37727ec681f3Smrg handle_begin_render_pass(cmd, state); 37737ec681f3Smrg break; 37747ec681f3Smrg case VK_CMD_BEGIN_RENDER_PASS2: 37757ec681f3Smrg handle_begin_render_pass2(cmd, state); 37767ec681f3Smrg break; 37777ec681f3Smrg case VK_CMD_NEXT_SUBPASS: 37787ec681f3Smrg case VK_CMD_NEXT_SUBPASS2: 37797ec681f3Smrg handle_next_subpass2(cmd, state); 37807ec681f3Smrg break; 37817ec681f3Smrg case VK_CMD_END_RENDER_PASS: 37827ec681f3Smrg case VK_CMD_END_RENDER_PASS2: 37837ec681f3Smrg handle_end_render_pass2(cmd, state); 37847ec681f3Smrg break; 37857ec681f3Smrg case VK_CMD_EXECUTE_COMMANDS: 37867ec681f3Smrg handle_execute_commands(cmd, state); 37877ec681f3Smrg break; 37887ec681f3Smrg case VK_CMD_DRAW_INDIRECT_COUNT: 37897ec681f3Smrg emit_state(state); 37907ec681f3Smrg handle_draw_indirect_count(cmd, state, false); 37917ec681f3Smrg break; 37927ec681f3Smrg case VK_CMD_DRAW_INDEXED_INDIRECT_COUNT: 37937ec681f3Smrg emit_state(state); 37947ec681f3Smrg handle_draw_indirect_count(cmd, state, true); 37957ec681f3Smrg break; 37967ec681f3Smrg case VK_CMD_PUSH_DESCRIPTOR_SET_KHR: 37977ec681f3Smrg handle_push_descriptor_set(cmd, state); 37987ec681f3Smrg break; 37997ec681f3Smrg case VK_CMD_PUSH_DESCRIPTOR_SET_WITH_TEMPLATE_KHR: 38007ec681f3Smrg handle_push_descriptor_set_with_template(cmd, state); 38017ec681f3Smrg break; 38027ec681f3Smrg case VK_CMD_BIND_TRANSFORM_FEEDBACK_BUFFERS_EXT: 38037ec681f3Smrg handle_bind_transform_feedback_buffers(cmd, state); 38047ec681f3Smrg break; 38057ec681f3Smrg case VK_CMD_BEGIN_TRANSFORM_FEEDBACK_EXT: 38067ec681f3Smrg handle_begin_transform_feedback(cmd, state); 38077ec681f3Smrg break; 38087ec681f3Smrg case VK_CMD_END_TRANSFORM_FEEDBACK_EXT: 38097ec681f3Smrg handle_end_transform_feedback(cmd, state); 38107ec681f3Smrg break; 38117ec681f3Smrg case VK_CMD_DRAW_INDIRECT_BYTE_COUNT_EXT: 38127ec681f3Smrg emit_state(state); 38137ec681f3Smrg handle_draw_indirect_byte_count(cmd, state); 38147ec681f3Smrg break; 38157ec681f3Smrg case VK_CMD_BEGIN_CONDITIONAL_RENDERING_EXT: 38167ec681f3Smrg handle_begin_conditional_rendering(cmd, state); 38177ec681f3Smrg break; 38187ec681f3Smrg case VK_CMD_END_CONDITIONAL_RENDERING_EXT: 38197ec681f3Smrg handle_end_conditional_rendering(state); 38207ec681f3Smrg break; 38217ec681f3Smrg case VK_CMD_SET_VERTEX_INPUT_EXT: 38227ec681f3Smrg handle_set_vertex_input(cmd, state); 38237ec681f3Smrg break; 38247ec681f3Smrg case VK_CMD_SET_CULL_MODE_EXT: 38257ec681f3Smrg handle_set_cull_mode(cmd, state); 38267ec681f3Smrg break; 38277ec681f3Smrg case VK_CMD_SET_FRONT_FACE_EXT: 38287ec681f3Smrg handle_set_front_face(cmd, state); 38297ec681f3Smrg break; 38307ec681f3Smrg case VK_CMD_SET_PRIMITIVE_TOPOLOGY_EXT: 38317ec681f3Smrg handle_set_primitive_topology(cmd, state); 38327ec681f3Smrg break; 38337ec681f3Smrg case VK_CMD_SET_DEPTH_TEST_ENABLE_EXT: 38347ec681f3Smrg handle_set_depth_test_enable(cmd, state); 38357ec681f3Smrg break; 38367ec681f3Smrg case VK_CMD_SET_DEPTH_WRITE_ENABLE_EXT: 38377ec681f3Smrg handle_set_depth_write_enable(cmd, state); 38387ec681f3Smrg break; 38397ec681f3Smrg case VK_CMD_SET_DEPTH_COMPARE_OP_EXT: 38407ec681f3Smrg handle_set_depth_compare_op(cmd, state); 38417ec681f3Smrg break; 38427ec681f3Smrg case VK_CMD_SET_DEPTH_BOUNDS_TEST_ENABLE_EXT: 38437ec681f3Smrg handle_set_depth_bounds_test_enable(cmd, state); 38447ec681f3Smrg break; 38457ec681f3Smrg case VK_CMD_SET_STENCIL_TEST_ENABLE_EXT: 38467ec681f3Smrg handle_set_stencil_test_enable(cmd, state); 38477ec681f3Smrg break; 38487ec681f3Smrg case VK_CMD_SET_STENCIL_OP_EXT: 38497ec681f3Smrg handle_set_stencil_op(cmd, state); 38507ec681f3Smrg break; 38517ec681f3Smrg case VK_CMD_SET_LINE_STIPPLE_EXT: 38527ec681f3Smrg handle_set_line_stipple(cmd, state); 38537ec681f3Smrg break; 38547ec681f3Smrg case VK_CMD_SET_DEPTH_BIAS_ENABLE_EXT: 38557ec681f3Smrg handle_set_depth_bias_enable(cmd, state); 38567ec681f3Smrg break; 38577ec681f3Smrg case VK_CMD_SET_LOGIC_OP_EXT: 38587ec681f3Smrg handle_set_logic_op(cmd, state); 38597ec681f3Smrg break; 38607ec681f3Smrg case VK_CMD_SET_PATCH_CONTROL_POINTS_EXT: 38617ec681f3Smrg handle_set_patch_control_points(cmd, state); 38627ec681f3Smrg break; 38637ec681f3Smrg case VK_CMD_SET_PRIMITIVE_RESTART_ENABLE_EXT: 38647ec681f3Smrg handle_set_primitive_restart_enable(cmd, state); 38657ec681f3Smrg break; 38667ec681f3Smrg case VK_CMD_SET_RASTERIZER_DISCARD_ENABLE_EXT: 38677ec681f3Smrg handle_set_rasterizer_discard_enable(cmd, state); 38687ec681f3Smrg break; 38697ec681f3Smrg case VK_CMD_SET_COLOR_WRITE_ENABLE_EXT: 38707ec681f3Smrg handle_set_color_write_enable(cmd, state); 38717ec681f3Smrg break; 38727ec681f3Smrg case VK_CMD_SET_DEVICE_MASK: 38737ec681f3Smrg /* no-op */ 38747ec681f3Smrg break; 38757ec681f3Smrg default: 38767ec681f3Smrg fprintf(stderr, "Unsupported command %s\n", vk_cmd_queue_type_names[cmd->type]); 38777ec681f3Smrg unreachable("Unsupported command"); 38787ec681f3Smrg break; 38797ec681f3Smrg } 38807ec681f3Smrg first = false; 38817ec681f3Smrg did_flush = false; 38827ec681f3Smrg } 38837ec681f3Smrg} 38847ec681f3Smrg 38857ec681f3SmrgVkResult lvp_execute_cmds(struct lvp_device *device, 38867ec681f3Smrg struct lvp_queue *queue, 38877ec681f3Smrg struct lvp_cmd_buffer *cmd_buffer) 38887ec681f3Smrg{ 38897ec681f3Smrg struct rendering_state state; 38907ec681f3Smrg memset(&state, 0, sizeof(state)); 38917ec681f3Smrg state.pctx = queue->ctx; 38927ec681f3Smrg state.cso = queue->cso; 38937ec681f3Smrg state.blend_dirty = true; 38947ec681f3Smrg state.dsa_dirty = true; 38957ec681f3Smrg state.rs_dirty = true; 38967ec681f3Smrg state.vp_dirty = true; 38977ec681f3Smrg for (enum pipe_shader_type s = PIPE_SHADER_VERTEX; s < PIPE_SHADER_TYPES; s++) { 38987ec681f3Smrg for (unsigned i = 0; i < PIPE_MAX_SAMPLERS; i++) 38997ec681f3Smrg state.cso_ss_ptr[s][i] = &state.ss[s][i]; 39007ec681f3Smrg } 39017ec681f3Smrg /* create a gallium context */ 39027ec681f3Smrg lvp_execute_cmd_buffer(cmd_buffer, &state); 39037ec681f3Smrg 39047ec681f3Smrg state.start_vb = -1; 39057ec681f3Smrg state.num_vb = 0; 39067ec681f3Smrg cso_unbind_context(queue->cso); 39077ec681f3Smrg for (unsigned i = 0; i < PIPE_MAX_SO_BUFFERS; i++) { 39087ec681f3Smrg if (state.so_targets[i]) { 39097ec681f3Smrg state.pctx->stream_output_target_destroy(state.pctx, state.so_targets[i]); 39107ec681f3Smrg } 39117ec681f3Smrg } 39127ec681f3Smrg 39137ec681f3Smrg for (enum pipe_shader_type s = PIPE_SHADER_VERTEX; s < PIPE_SHADER_TYPES; s++) { 39147ec681f3Smrg for (unsigned i = 0; i < PIPE_MAX_SAMPLERS; i++) { 39157ec681f3Smrg if (state.sv[s][i]) 39167ec681f3Smrg pipe_sampler_view_reference(&state.sv[s][i], NULL); 39177ec681f3Smrg } 39187ec681f3Smrg } 39197ec681f3Smrg 39207ec681f3Smrg for (unsigned i = 0; i < PIPE_MAX_SAMPLERS; i++) { 39217ec681f3Smrg if (state.cso_ss_ptr[PIPE_SHADER_COMPUTE][i]) 39227ec681f3Smrg state.pctx->delete_sampler_state(state.pctx, state.ss_cso[PIPE_SHADER_COMPUTE][i]); 39237ec681f3Smrg } 39247ec681f3Smrg 39257ec681f3Smrg free(state.imageless_views); 39267ec681f3Smrg free(state.pending_clear_aspects); 39277ec681f3Smrg free(state.cleared_views); 39287ec681f3Smrg free(state.attachments); 39297ec681f3Smrg return VK_SUCCESS; 39307ec681f3Smrg} 3931