Path: blob/21.2-virgl/src/amd/vulkan/radv_meta.c
7202 views
/*1* Copyright © 2016 Red Hat2* based on intel anv code:3* Copyright © 2015 Intel Corporation4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the "Software"),7* to deal in the Software without restriction, including without limitation8* the rights to use, copy, modify, merge, publish, distribute, sublicense,9* and/or sell copies of the Software, and to permit persons to whom the10* Software is furnished to do so, subject to the following conditions:11*12* The above copyright notice and this permission notice (including the next13* paragraph) shall be included in all copies or substantial portions of the14* Software.15*16* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR17* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,18* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL19* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER20* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING21* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS22* IN THE SOFTWARE.23*/2425#include "radv_meta.h"2627#include "vk_util.h"2829#include <fcntl.h>30#include <limits.h>31#ifndef _WIN3232#include <pwd.h>33#endif34#include <sys/stat.h>3536void37radv_meta_save(struct radv_meta_saved_state *state, struct radv_cmd_buffer *cmd_buffer,38uint32_t flags)39{40VkPipelineBindPoint bind_point = flags & RADV_META_SAVE_GRAPHICS_PIPELINE41? VK_PIPELINE_BIND_POINT_GRAPHICS42: VK_PIPELINE_BIND_POINT_COMPUTE;43struct radv_descriptor_state *descriptors_state =44radv_get_descriptors_state(cmd_buffer, bind_point);4546assert(flags & (RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_COMPUTE_PIPELINE));4748state->flags = flags;4950if (state->flags & RADV_META_SAVE_GRAPHICS_PIPELINE) {51assert(!(state->flags & RADV_META_SAVE_COMPUTE_PIPELINE));5253state->old_pipeline = cmd_buffer->state.pipeline;5455/* Save all viewports. */56state->viewport.count = cmd_buffer->state.dynamic.viewport.count;57typed_memcpy(state->viewport.viewports, cmd_buffer->state.dynamic.viewport.viewports,58MAX_VIEWPORTS);5960/* Save all scissors. */61state->scissor.count = cmd_buffer->state.dynamic.scissor.count;62typed_memcpy(state->scissor.scissors, cmd_buffer->state.dynamic.scissor.scissors,63MAX_SCISSORS);6465state->cull_mode = cmd_buffer->state.dynamic.cull_mode;66state->front_face = cmd_buffer->state.dynamic.front_face;6768state->primitive_topology = cmd_buffer->state.dynamic.primitive_topology;6970state->depth_test_enable = cmd_buffer->state.dynamic.depth_test_enable;71state->depth_write_enable = cmd_buffer->state.dynamic.depth_write_enable;72state->depth_compare_op = cmd_buffer->state.dynamic.depth_compare_op;73state->depth_bounds_test_enable = cmd_buffer->state.dynamic.depth_bounds_test_enable;74state->stencil_test_enable = cmd_buffer->state.dynamic.stencil_test_enable;7576state->stencil_op.front.compare_op = cmd_buffer->state.dynamic.stencil_op.front.compare_op;77state->stencil_op.front.fail_op = cmd_buffer->state.dynamic.stencil_op.front.fail_op;78state->stencil_op.front.pass_op = cmd_buffer->state.dynamic.stencil_op.front.pass_op;79state->stencil_op.front.depth_fail_op =80cmd_buffer->state.dynamic.stencil_op.front.depth_fail_op;8182state->stencil_op.back.compare_op = cmd_buffer->state.dynamic.stencil_op.back.compare_op;83state->stencil_op.back.fail_op = cmd_buffer->state.dynamic.stencil_op.back.fail_op;84state->stencil_op.back.pass_op = cmd_buffer->state.dynamic.stencil_op.back.pass_op;85state->stencil_op.back.depth_fail_op =86cmd_buffer->state.dynamic.stencil_op.back.depth_fail_op;8788state->fragment_shading_rate.size = cmd_buffer->state.dynamic.fragment_shading_rate.size;89state->fragment_shading_rate.combiner_ops[0] =90cmd_buffer->state.dynamic.fragment_shading_rate.combiner_ops[0];91state->fragment_shading_rate.combiner_ops[1] =92cmd_buffer->state.dynamic.fragment_shading_rate.combiner_ops[1];9394state->depth_bias_enable = cmd_buffer->state.dynamic.depth_bias_enable;9596state->primitive_restart_enable = cmd_buffer->state.dynamic.primitive_restart_enable;9798state->rasterizer_discard_enable = cmd_buffer->state.dynamic.rasterizer_discard_enable;99100state->logic_op = cmd_buffer->state.dynamic.logic_op;101102state->color_write_enable = cmd_buffer->state.dynamic.color_write_enable;103}104105if (state->flags & RADV_META_SAVE_SAMPLE_LOCATIONS) {106typed_memcpy(&state->sample_location, &cmd_buffer->state.dynamic.sample_location, 1);107}108109if (state->flags & RADV_META_SAVE_COMPUTE_PIPELINE) {110assert(!(state->flags & RADV_META_SAVE_GRAPHICS_PIPELINE));111112state->old_pipeline = cmd_buffer->state.compute_pipeline;113}114115if (state->flags & RADV_META_SAVE_DESCRIPTORS) {116state->old_descriptor_set0 = descriptors_state->sets[0];117if (!(descriptors_state->valid & 1) || !state->old_descriptor_set0)118state->flags &= ~RADV_META_SAVE_DESCRIPTORS;119}120121if (state->flags & RADV_META_SAVE_CONSTANTS) {122memcpy(state->push_constants, cmd_buffer->push_constants, MAX_PUSH_CONSTANTS_SIZE);123}124125if (state->flags & RADV_META_SAVE_PASS) {126state->pass = cmd_buffer->state.pass;127state->subpass = cmd_buffer->state.subpass;128state->framebuffer = cmd_buffer->state.framebuffer;129state->attachments = cmd_buffer->state.attachments;130state->render_area = cmd_buffer->state.render_area;131}132}133134void135radv_meta_restore(const struct radv_meta_saved_state *state, struct radv_cmd_buffer *cmd_buffer)136{137VkPipelineBindPoint bind_point = state->flags & RADV_META_SAVE_GRAPHICS_PIPELINE138? VK_PIPELINE_BIND_POINT_GRAPHICS139: VK_PIPELINE_BIND_POINT_COMPUTE;140141if (state->flags & RADV_META_SAVE_GRAPHICS_PIPELINE) {142radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS,143radv_pipeline_to_handle(state->old_pipeline));144145cmd_buffer->state.dirty |= RADV_CMD_DIRTY_PIPELINE;146147/* Restore all viewports. */148cmd_buffer->state.dynamic.viewport.count = state->viewport.count;149typed_memcpy(cmd_buffer->state.dynamic.viewport.viewports, state->viewport.viewports,150MAX_VIEWPORTS);151152/* Restore all scissors. */153cmd_buffer->state.dynamic.scissor.count = state->scissor.count;154typed_memcpy(cmd_buffer->state.dynamic.scissor.scissors, state->scissor.scissors,155MAX_SCISSORS);156157cmd_buffer->state.dynamic.cull_mode = state->cull_mode;158cmd_buffer->state.dynamic.front_face = state->front_face;159160cmd_buffer->state.dynamic.primitive_topology = state->primitive_topology;161162cmd_buffer->state.dynamic.depth_test_enable = state->depth_test_enable;163cmd_buffer->state.dynamic.depth_write_enable = state->depth_write_enable;164cmd_buffer->state.dynamic.depth_compare_op = state->depth_compare_op;165cmd_buffer->state.dynamic.depth_bounds_test_enable = state->depth_bounds_test_enable;166cmd_buffer->state.dynamic.stencil_test_enable = state->stencil_test_enable;167168cmd_buffer->state.dynamic.stencil_op.front.compare_op = state->stencil_op.front.compare_op;169cmd_buffer->state.dynamic.stencil_op.front.fail_op = state->stencil_op.front.fail_op;170cmd_buffer->state.dynamic.stencil_op.front.pass_op = state->stencil_op.front.pass_op;171cmd_buffer->state.dynamic.stencil_op.front.depth_fail_op =172state->stencil_op.front.depth_fail_op;173174cmd_buffer->state.dynamic.stencil_op.back.compare_op = state->stencil_op.back.compare_op;175cmd_buffer->state.dynamic.stencil_op.back.fail_op = state->stencil_op.back.fail_op;176cmd_buffer->state.dynamic.stencil_op.back.pass_op = state->stencil_op.back.pass_op;177cmd_buffer->state.dynamic.stencil_op.back.depth_fail_op =178state->stencil_op.back.depth_fail_op;179180cmd_buffer->state.dynamic.fragment_shading_rate.size = state->fragment_shading_rate.size;181cmd_buffer->state.dynamic.fragment_shading_rate.combiner_ops[0] =182state->fragment_shading_rate.combiner_ops[0];183cmd_buffer->state.dynamic.fragment_shading_rate.combiner_ops[1] =184state->fragment_shading_rate.combiner_ops[1];185186cmd_buffer->state.dynamic.depth_bias_enable = state->depth_bias_enable;187188cmd_buffer->state.dynamic.primitive_restart_enable = state->primitive_restart_enable;189190cmd_buffer->state.dynamic.rasterizer_discard_enable = state->rasterizer_discard_enable;191192cmd_buffer->state.dynamic.logic_op = state->logic_op;193194cmd_buffer->state.dynamic.color_write_enable = state->color_write_enable;195196cmd_buffer->state.dirty |=197RADV_CMD_DIRTY_DYNAMIC_VIEWPORT | RADV_CMD_DIRTY_DYNAMIC_SCISSOR |198RADV_CMD_DIRTY_DYNAMIC_CULL_MODE | RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE |199RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY | RADV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE |200RADV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE | RADV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP |201RADV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE |202RADV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE | RADV_CMD_DIRTY_DYNAMIC_STENCIL_OP |203RADV_CMD_DIRTY_DYNAMIC_FRAGMENT_SHADING_RATE | RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE |204RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE |205RADV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE | RADV_CMD_DIRTY_DYNAMIC_LOGIC_OP |206RADV_CMD_DIRTY_DYNAMIC_COLOR_WRITE_ENABLE;207}208209if (state->flags & RADV_META_SAVE_SAMPLE_LOCATIONS) {210typed_memcpy(&cmd_buffer->state.dynamic.sample_location.locations,211&state->sample_location.locations, 1);212213cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS;214}215216if (state->flags & RADV_META_SAVE_COMPUTE_PIPELINE) {217radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE,218radv_pipeline_to_handle(state->old_pipeline));219}220221if (state->flags & RADV_META_SAVE_DESCRIPTORS) {222radv_set_descriptor_set(cmd_buffer, bind_point, state->old_descriptor_set0, 0);223}224225if (state->flags & RADV_META_SAVE_CONSTANTS) {226VkShaderStageFlags stages = VK_SHADER_STAGE_COMPUTE_BIT;227228if (state->flags & RADV_META_SAVE_GRAPHICS_PIPELINE)229stages |= VK_SHADER_STAGE_ALL_GRAPHICS;230231radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), VK_NULL_HANDLE, stages, 0,232MAX_PUSH_CONSTANTS_SIZE, state->push_constants);233}234235if (state->flags & RADV_META_SAVE_PASS) {236cmd_buffer->state.pass = state->pass;237cmd_buffer->state.subpass = state->subpass;238cmd_buffer->state.framebuffer = state->framebuffer;239cmd_buffer->state.attachments = state->attachments;240cmd_buffer->state.render_area = state->render_area;241if (state->subpass)242cmd_buffer->state.dirty |= RADV_CMD_DIRTY_FRAMEBUFFER;243}244}245246VkImageViewType247radv_meta_get_view_type(const struct radv_image *image)248{249switch (image->type) {250case VK_IMAGE_TYPE_1D:251return VK_IMAGE_VIEW_TYPE_1D;252case VK_IMAGE_TYPE_2D:253return VK_IMAGE_VIEW_TYPE_2D;254case VK_IMAGE_TYPE_3D:255return VK_IMAGE_VIEW_TYPE_3D;256default:257unreachable("bad VkImageViewType");258}259}260261/**262* When creating a destination VkImageView, this function provides the needed263* VkImageViewCreateInfo::subresourceRange::baseArrayLayer.264*/265uint32_t266radv_meta_get_iview_layer(const struct radv_image *dest_image,267const VkImageSubresourceLayers *dest_subresource,268const VkOffset3D *dest_offset)269{270switch (dest_image->type) {271case VK_IMAGE_TYPE_1D:272case VK_IMAGE_TYPE_2D:273return dest_subresource->baseArrayLayer;274case VK_IMAGE_TYPE_3D:275/* HACK: Vulkan does not allow attaching a 3D image to a framebuffer,276* but meta does it anyway. When doing so, we translate the277* destination's z offset into an array offset.278*/279return dest_offset->z;280default:281assert(!"bad VkImageType");282return 0;283}284}285286static void *287meta_alloc(void *_device, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)288{289struct radv_device *device = _device;290return device->vk.alloc.pfnAllocation(device->vk.alloc.pUserData, size, alignment,291VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);292}293294static void *295meta_realloc(void *_device, void *original, size_t size, size_t alignment,296VkSystemAllocationScope allocationScope)297{298struct radv_device *device = _device;299return device->vk.alloc.pfnReallocation(device->vk.alloc.pUserData, original, size, alignment,300VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);301}302303static void304meta_free(void *_device, void *data)305{306struct radv_device *device = _device;307device->vk.alloc.pfnFree(device->vk.alloc.pUserData, data);308}309310#ifndef _WIN32311static bool312radv_builtin_cache_path(char *path)313{314char *xdg_cache_home = getenv("XDG_CACHE_HOME");315const char *suffix = "/radv_builtin_shaders";316const char *suffix2 = "/.cache/radv_builtin_shaders";317struct passwd pwd, *result;318char path2[PATH_MAX + 1]; /* PATH_MAX is not a real max,but suffices here. */319int ret;320321if (xdg_cache_home) {322ret = snprintf(path, PATH_MAX + 1, "%s%s%zd", xdg_cache_home, suffix, sizeof(void *) * 8);323return ret > 0 && ret < PATH_MAX + 1;324}325326getpwuid_r(getuid(), &pwd, path2, PATH_MAX - strlen(suffix2), &result);327if (!result)328return false;329330strcpy(path, pwd.pw_dir);331strcat(path, "/.cache");332if (mkdir(path, 0755) && errno != EEXIST)333return false;334335ret = snprintf(path, PATH_MAX + 1, "%s%s%zd", pwd.pw_dir, suffix2, sizeof(void *) * 8);336return ret > 0 && ret < PATH_MAX + 1;337}338#endif339340static bool341radv_load_meta_pipeline(struct radv_device *device)342{343#ifdef _WIN32344return false;345#else346char path[PATH_MAX + 1];347struct stat st;348void *data = NULL;349bool ret = false;350351if (!radv_builtin_cache_path(path))352return false;353354int fd = open(path, O_RDONLY);355if (fd < 0)356return false;357if (fstat(fd, &st))358goto fail;359data = malloc(st.st_size);360if (!data)361goto fail;362if (read(fd, data, st.st_size) == -1)363goto fail;364365ret = radv_pipeline_cache_load(&device->meta_state.cache, data, st.st_size);366fail:367free(data);368close(fd);369return ret;370#endif371}372373static void374radv_store_meta_pipeline(struct radv_device *device)375{376#ifndef _WIN32377char path[PATH_MAX + 1], path2[PATH_MAX + 7];378size_t size;379void *data = NULL;380381if (!device->meta_state.cache.modified)382return;383384if (radv_GetPipelineCacheData(radv_device_to_handle(device),385radv_pipeline_cache_to_handle(&device->meta_state.cache), &size,386NULL))387return;388389if (!radv_builtin_cache_path(path))390return;391392strcpy(path2, path);393strcat(path2, "XXXXXX");394int fd = mkstemp(path2); // open(path, O_WRONLY | O_CREAT, 0600);395if (fd < 0)396return;397data = malloc(size);398if (!data)399goto fail;400401if (radv_GetPipelineCacheData(radv_device_to_handle(device),402radv_pipeline_cache_to_handle(&device->meta_state.cache), &size,403data))404goto fail;405if (write(fd, data, size) == -1)406goto fail;407408rename(path2, path);409fail:410free(data);411close(fd);412unlink(path2);413#endif414}415416VkResult417radv_device_init_meta(struct radv_device *device)418{419VkResult result;420421memset(&device->meta_state, 0, sizeof(device->meta_state));422423device->meta_state.alloc = (VkAllocationCallbacks){424.pUserData = device,425.pfnAllocation = meta_alloc,426.pfnReallocation = meta_realloc,427.pfnFree = meta_free,428};429430device->meta_state.cache.alloc = device->meta_state.alloc;431radv_pipeline_cache_init(&device->meta_state.cache, device);432bool loaded_cache = radv_load_meta_pipeline(device);433bool on_demand = !loaded_cache;434435mtx_init(&device->meta_state.mtx, mtx_plain);436437result = radv_device_init_meta_clear_state(device, on_demand);438if (result != VK_SUCCESS)439goto fail_clear;440441result = radv_device_init_meta_resolve_state(device, on_demand);442if (result != VK_SUCCESS)443goto fail_resolve;444445result = radv_device_init_meta_blit_state(device, on_demand);446if (result != VK_SUCCESS)447goto fail_blit;448449result = radv_device_init_meta_blit2d_state(device, on_demand);450if (result != VK_SUCCESS)451goto fail_blit2d;452453result = radv_device_init_meta_bufimage_state(device);454if (result != VK_SUCCESS)455goto fail_bufimage;456457result = radv_device_init_meta_depth_decomp_state(device, on_demand);458if (result != VK_SUCCESS)459goto fail_depth_decomp;460461result = radv_device_init_meta_buffer_state(device);462if (result != VK_SUCCESS)463goto fail_buffer;464465result = radv_device_init_meta_query_state(device, on_demand);466if (result != VK_SUCCESS)467goto fail_query;468469result = radv_device_init_meta_fast_clear_flush_state(device, on_demand);470if (result != VK_SUCCESS)471goto fail_fast_clear;472473result = radv_device_init_meta_resolve_compute_state(device, on_demand);474if (result != VK_SUCCESS)475goto fail_resolve_compute;476477result = radv_device_init_meta_resolve_fragment_state(device, on_demand);478if (result != VK_SUCCESS)479goto fail_resolve_fragment;480481result = radv_device_init_meta_fmask_expand_state(device);482if (result != VK_SUCCESS)483goto fail_fmask_expand;484485result = radv_device_init_accel_struct_build_state(device);486if (result != VK_SUCCESS)487goto fail_accel_struct_build;488489return VK_SUCCESS;490491fail_accel_struct_build:492radv_device_finish_meta_fmask_expand_state(device);493fail_fmask_expand:494radv_device_finish_meta_resolve_fragment_state(device);495fail_resolve_fragment:496radv_device_finish_meta_resolve_compute_state(device);497fail_resolve_compute:498radv_device_finish_meta_fast_clear_flush_state(device);499fail_fast_clear:500radv_device_finish_meta_query_state(device);501fail_query:502radv_device_finish_meta_buffer_state(device);503fail_buffer:504radv_device_finish_meta_depth_decomp_state(device);505fail_depth_decomp:506radv_device_finish_meta_bufimage_state(device);507fail_bufimage:508radv_device_finish_meta_blit2d_state(device);509fail_blit2d:510radv_device_finish_meta_blit_state(device);511fail_blit:512radv_device_finish_meta_resolve_state(device);513fail_resolve:514radv_device_finish_meta_clear_state(device);515fail_clear:516mtx_destroy(&device->meta_state.mtx);517radv_pipeline_cache_finish(&device->meta_state.cache);518return result;519}520521void522radv_device_finish_meta(struct radv_device *device)523{524radv_device_finish_accel_struct_build_state(device);525radv_device_finish_meta_clear_state(device);526radv_device_finish_meta_resolve_state(device);527radv_device_finish_meta_blit_state(device);528radv_device_finish_meta_blit2d_state(device);529radv_device_finish_meta_bufimage_state(device);530radv_device_finish_meta_depth_decomp_state(device);531radv_device_finish_meta_query_state(device);532radv_device_finish_meta_buffer_state(device);533radv_device_finish_meta_fast_clear_flush_state(device);534radv_device_finish_meta_resolve_compute_state(device);535radv_device_finish_meta_resolve_fragment_state(device);536radv_device_finish_meta_fmask_expand_state(device);537radv_device_finish_meta_dcc_retile_state(device);538radv_device_finish_meta_copy_vrs_htile_state(device);539540radv_store_meta_pipeline(device);541radv_pipeline_cache_finish(&device->meta_state.cache);542mtx_destroy(&device->meta_state.mtx);543}544545nir_ssa_def *546radv_meta_gen_rect_vertices_comp2(nir_builder *vs_b, nir_ssa_def *comp2)547{548549nir_ssa_def *vertex_id = nir_load_vertex_id_zero_base(vs_b);550551/* vertex 0 - -1.0, -1.0 */552/* vertex 1 - -1.0, 1.0 */553/* vertex 2 - 1.0, -1.0 */554/* so channel 0 is vertex_id != 2 ? -1.0 : 1.0555channel 1 is vertex id != 1 ? -1.0 : 1.0 */556557nir_ssa_def *c0cmp = nir_ine(vs_b, vertex_id, nir_imm_int(vs_b, 2));558nir_ssa_def *c1cmp = nir_ine(vs_b, vertex_id, nir_imm_int(vs_b, 1));559560nir_ssa_def *comp[4];561comp[0] = nir_bcsel(vs_b, c0cmp, nir_imm_float(vs_b, -1.0), nir_imm_float(vs_b, 1.0));562563comp[1] = nir_bcsel(vs_b, c1cmp, nir_imm_float(vs_b, -1.0), nir_imm_float(vs_b, 1.0));564comp[2] = comp2;565comp[3] = nir_imm_float(vs_b, 1.0);566nir_ssa_def *outvec = nir_vec(vs_b, comp, 4);567568return outvec;569}570571nir_ssa_def *572radv_meta_gen_rect_vertices(nir_builder *vs_b)573{574return radv_meta_gen_rect_vertices_comp2(vs_b, nir_imm_float(vs_b, 0.0));575}576577/* vertex shader that generates vertices */578nir_shader *579radv_meta_build_nir_vs_generate_vertices(void)580{581const struct glsl_type *vec4 = glsl_vec4_type();582583nir_variable *v_position;584585nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_VERTEX, NULL, "meta_vs_gen_verts");586587nir_ssa_def *outvec = radv_meta_gen_rect_vertices(&b);588589v_position = nir_variable_create(b.shader, nir_var_shader_out, vec4, "gl_Position");590v_position->data.location = VARYING_SLOT_POS;591592nir_store_var(&b, v_position, outvec, 0xf);593594return b.shader;595}596597nir_shader *598radv_meta_build_nir_fs_noop(void)599{600nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, NULL, "meta_noop_fs");601602return b.shader;603}604605void606radv_meta_build_resolve_shader_core(nir_builder *b, bool is_integer, int samples,607nir_variable *input_img, nir_variable *color,608nir_ssa_def *img_coord)609{610/* do a txf_ms on each sample */611nir_ssa_def *tmp;612bool inserted_if = false;613614nir_ssa_def *input_img_deref = &nir_build_deref_var(b, input_img)->dest.ssa;615616nir_tex_instr *tex = nir_tex_instr_create(b->shader, 3);617tex->sampler_dim = GLSL_SAMPLER_DIM_MS;618tex->op = nir_texop_txf_ms;619tex->src[0].src_type = nir_tex_src_coord;620tex->src[0].src = nir_src_for_ssa(img_coord);621tex->src[1].src_type = nir_tex_src_ms_index;622tex->src[1].src = nir_src_for_ssa(nir_imm_int(b, 0));623tex->src[2].src_type = nir_tex_src_texture_deref;624tex->src[2].src = nir_src_for_ssa(input_img_deref);625tex->dest_type = nir_type_float32;626tex->is_array = false;627tex->coord_components = 2;628629nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");630nir_builder_instr_insert(b, &tex->instr);631632tmp = &tex->dest.ssa;633634if (!is_integer && samples > 1) {635nir_tex_instr *tex_all_same = nir_tex_instr_create(b->shader, 2);636tex_all_same->sampler_dim = GLSL_SAMPLER_DIM_MS;637tex_all_same->op = nir_texop_samples_identical;638tex_all_same->src[0].src_type = nir_tex_src_coord;639tex_all_same->src[0].src = nir_src_for_ssa(img_coord);640tex_all_same->src[1].src_type = nir_tex_src_texture_deref;641tex_all_same->src[1].src = nir_src_for_ssa(input_img_deref);642tex_all_same->dest_type = nir_type_bool1;643tex_all_same->is_array = false;644tex_all_same->coord_components = 2;645646nir_ssa_dest_init(&tex_all_same->instr, &tex_all_same->dest, 1, 1, "tex");647nir_builder_instr_insert(b, &tex_all_same->instr);648649nir_ssa_def *all_same = nir_ieq(b, &tex_all_same->dest.ssa, nir_imm_bool(b, false));650nir_push_if(b, all_same);651for (int i = 1; i < samples; i++) {652nir_tex_instr *tex_add = nir_tex_instr_create(b->shader, 3);653tex_add->sampler_dim = GLSL_SAMPLER_DIM_MS;654tex_add->op = nir_texop_txf_ms;655tex_add->src[0].src_type = nir_tex_src_coord;656tex_add->src[0].src = nir_src_for_ssa(img_coord);657tex_add->src[1].src_type = nir_tex_src_ms_index;658tex_add->src[1].src = nir_src_for_ssa(nir_imm_int(b, i));659tex_add->src[2].src_type = nir_tex_src_texture_deref;660tex_add->src[2].src = nir_src_for_ssa(input_img_deref);661tex_add->dest_type = nir_type_float32;662tex_add->is_array = false;663tex_add->coord_components = 2;664665nir_ssa_dest_init(&tex_add->instr, &tex_add->dest, 4, 32, "tex");666nir_builder_instr_insert(b, &tex_add->instr);667668tmp = nir_fadd(b, tmp, &tex_add->dest.ssa);669}670671tmp = nir_fdiv(b, tmp, nir_imm_float(b, samples));672nir_store_var(b, color, tmp, 0xf);673nir_push_else(b, NULL);674inserted_if = true;675}676nir_store_var(b, color, &tex->dest.ssa, 0xf);677678if (inserted_if)679nir_pop_if(b, NULL);680}681682nir_ssa_def *683radv_meta_load_descriptor(nir_builder *b, unsigned desc_set, unsigned binding)684{685nir_ssa_def *rsrc = nir_vulkan_resource_index(b, 3, 32, nir_imm_int(b, 0), .desc_set = desc_set,686.binding = binding);687return nir_channels(b, rsrc, 0x3);688}689690691