X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Ffreedreno%2Fvulkan%2Ftu_shader.c;h=29ac80bc48db4ebb0087bbb162b87b037c4d2573;hb=5c9728d960714b1c5eb4806a80157ce95992fcfe;hp=bd52335093da3a9bdd66147d91f1781f9158d56f;hpb=d6a8591f72a9f1ce48dc0eefdb89cc0825e8acf7;p=mesa.git diff --git a/src/freedreno/vulkan/tu_shader.c b/src/freedreno/vulkan/tu_shader.c index bd52335093d..29ac80bc48d 100644 --- a/src/freedreno/vulkan/tu_shader.c +++ b/src/freedreno/vulkan/tu_shader.c @@ -26,6 +26,8 @@ #include "spirv/nir_spirv.h" #include "util/mesa-sha1.h" #include "nir/nir_xfb_info.h" +#include "nir/nir_vulkan.h" +#include "vk_util.h" #include "ir3/ir3_nir.h" @@ -52,7 +54,7 @@ tu_spirv_to_nir(struct ir3_compiler *compiler, struct nir_spirv_specialization *spec = NULL; uint32_t num_spec = 0; if (spec_info && spec_info->mapEntryCount) { - spec = malloc(sizeof(*spec) * spec_info->mapEntryCount); + spec = calloc(spec_info->mapEntryCount, sizeof(*spec)); if (!spec) return NULL; @@ -61,10 +63,23 @@ tu_spirv_to_nir(struct ir3_compiler *compiler, const void *data = spec_info->pData + entry->offset; assert(data + entry->size <= spec_info->pData + spec_info->dataSize); spec[i].id = entry->constantID; - if (entry->size == 8) - spec[i].data64 = *(const uint64_t *) data; - else - spec[i].data32 = *(const uint32_t *) data; + switch (entry->size) { + case 8: + spec[i].value.u64 = *(const uint64_t *)data; + break; + case 4: + spec[i].value.u32 = *(const uint32_t *)data; + break; + case 2: + spec[i].value.u16 = *(const uint16_t *)data; + break; + case 1: + spec[i].value.u8 = *(const uint8_t *)data; + break; + default: + assert(!"Invalid spec constant size"); + break; + } spec[i].defined_on_module = false; } @@ -83,141 +98,20 @@ tu_spirv_to_nir(struct ir3_compiler *compiler, return nir; } -static unsigned -map_add(struct tu_descriptor_map *map, int set, int binding, int value, - int array_size) -{ - unsigned index = 0; - for (unsigned i = 0; i < map->num; i++) { - if (set == map->set[i] && binding == map->binding[i]) { - assert(value == map->value[i]); - assert(array_size == map->array_size[i]); - return index; - } - index += map->array_size[i]; - } - - assert(index == map->num_desc); - - map->set[map->num] = set; - map->binding[map->num] = binding; - map->value[map->num] = value; - map->array_size[map->num] = array_size; - map->num++; - map->num_desc += array_size; - - return index; -} - -static void -lower_tex_src_to_offset(nir_builder *b, nir_tex_instr *instr, unsigned src_idx, - struct tu_shader *shader, - const struct tu_pipeline_layout *layout) -{ - nir_ssa_def *index = NULL; - unsigned base_index = 0; - unsigned array_elements = 1; - nir_tex_src *src = &instr->src[src_idx]; - bool is_sampler = src->src_type == nir_tex_src_sampler_deref; - - /* We compute first the offsets */ - nir_deref_instr *deref = nir_instr_as_deref(src->src.ssa->parent_instr); - while (deref->deref_type != nir_deref_type_var) { - assert(deref->parent.is_ssa); - nir_deref_instr *parent = - nir_instr_as_deref(deref->parent.ssa->parent_instr); - - assert(deref->deref_type == nir_deref_type_array); - - if (nir_src_is_const(deref->arr.index) && index == NULL) { - /* We're still building a direct index */ - base_index += nir_src_as_uint(deref->arr.index) * array_elements; - } else { - if (index == NULL) { - /* We used to be direct but not anymore */ - index = nir_imm_int(b, base_index); - base_index = 0; - } - - index = nir_iadd(b, index, - nir_imul(b, nir_imm_int(b, array_elements), - nir_ssa_for_src(b, deref->arr.index, 1))); - } - - array_elements *= glsl_get_length(parent->type); - - deref = parent; - } - - if (index) - index = nir_umin(b, index, nir_imm_int(b, array_elements - 1)); - - /* We have the offsets, we apply them, rewriting the source or removing - * instr if needed - */ - if (index) { - nir_instr_rewrite_src(&instr->instr, &src->src, - nir_src_for_ssa(index)); - - src->src_type = is_sampler ? - nir_tex_src_sampler_offset : - nir_tex_src_texture_offset; - } else { - nir_tex_instr_remove_src(instr, src_idx); - } - - uint32_t set = deref->var->data.descriptor_set; - uint32_t binding = deref->var->data.binding; - struct tu_descriptor_set_layout *set_layout = layout->set[set].layout; - struct tu_descriptor_set_binding_layout *binding_layout = - &set_layout->binding[binding]; - - int desc_index = map_add(is_sampler ? - &shader->sampler_map : &shader->texture_map, - deref->var->data.descriptor_set, - deref->var->data.binding, - deref->var->data.index, - binding_layout->array_size) + base_index; - if (is_sampler) - instr->sampler_index = desc_index; - else - instr->texture_index = desc_index; -} - -static bool -lower_sampler(nir_builder *b, nir_tex_instr *instr, struct tu_shader *shader, - const struct tu_pipeline_layout *layout) -{ - int texture_idx = - nir_tex_instr_src_index(instr, nir_tex_src_texture_deref); - - if (texture_idx >= 0) - lower_tex_src_to_offset(b, instr, texture_idx, shader, layout); - - int sampler_idx = - nir_tex_instr_src_index(instr, nir_tex_src_sampler_deref); - - if (sampler_idx >= 0) - lower_tex_src_to_offset(b, instr, sampler_idx, shader, layout); - - if (texture_idx < 0 && sampler_idx < 0) - return false; - - return true; -} - static void lower_load_push_constant(nir_builder *b, nir_intrinsic_instr *instr, struct tu_shader *shader) { - /* note: ir3 wants load_ubo, not load_uniform */ - assert(nir_intrinsic_base(instr) == 0); - nir_intrinsic_instr *load = - nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_ubo); + nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_uniform); load->num_components = instr->num_components; - load->src[0] = nir_src_for_ssa(nir_imm_int(b, 0)); - load->src[1] = instr->src[0]; + uint32_t base = nir_intrinsic_base(instr); + assert(base % 4 == 0); + assert(base >= shader->push_consts.lo * 16); + base -= shader->push_consts.lo * 16; + nir_intrinsic_set_base(load, base / 4); + load->src[0] = + nir_src_for_ssa(nir_ushr(b, instr->src[0].ssa, nir_imm_int(b, 2))); nir_ssa_dest_init(&load->instr, &load->dest, load->num_components, instr->dest.ssa.bit_size, instr->dest.ssa.name); @@ -232,66 +126,108 @@ lower_vulkan_resource_index(nir_builder *b, nir_intrinsic_instr *instr, struct tu_shader *shader, const struct tu_pipeline_layout *layout) { - nir_const_value *const_val = nir_src_as_const_value(instr->src[0]); + nir_ssa_def *vulkan_idx = instr->src[0].ssa; unsigned set = nir_intrinsic_desc_set(instr); unsigned binding = nir_intrinsic_binding(instr); struct tu_descriptor_set_layout *set_layout = layout->set[set].layout; struct tu_descriptor_set_binding_layout *binding_layout = &set_layout->binding[binding]; - unsigned index = 0; + uint32_t base; - switch (nir_intrinsic_desc_type(instr)) { - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + switch (binding_layout->type) { case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - if (!const_val) - tu_finishme("non-constant vulkan_resource_index array index"); - /* skip index 0 which is used for push constants */ - index = map_add(&shader->ubo_map, set, binding, 0, - binding_layout->array_size) + 1; - index += const_val->u32; - break; - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: - if (!const_val) - tu_finishme("non-constant vulkan_resource_index array index"); - index = map_add(&shader->ssbo_map, set, binding, 0, - binding_layout->array_size); - index += const_val->u32; + base = layout->set[set].dynamic_offset_start + + binding_layout->dynamic_offset_offset + + layout->input_attachment_count; + set = MAX_SETS; break; default: - tu_finishme("unsupported desc_type for vulkan_resource_index"); + base = binding_layout->offset / (4 * A6XX_TEX_CONST_DWORDS); break; } + nir_intrinsic_instr *bindless = + nir_intrinsic_instr_create(b->shader, + nir_intrinsic_bindless_resource_ir3); + bindless->num_components = 1; + nir_ssa_dest_init(&bindless->instr, &bindless->dest, + 1, 32, NULL); + nir_intrinsic_set_desc_set(bindless, set); + bindless->src[0] = nir_src_for_ssa(nir_iadd(b, nir_imm_int(b, base), vulkan_idx)); + nir_builder_instr_insert(b, &bindless->instr); + nir_ssa_def_rewrite_uses(&instr->dest.ssa, - nir_src_for_ssa(nir_imm_int(b, index))); + nir_src_for_ssa(&bindless->dest.ssa)); nir_instr_remove(&instr->instr); } -static void -lower_image_deref(nir_builder *b, - nir_intrinsic_instr *instr, struct tu_shader *shader, - const struct tu_pipeline_layout *layout) +static nir_ssa_def * +build_bindless(nir_builder *b, nir_deref_instr *deref, bool is_sampler, + struct tu_shader *shader, + const struct tu_pipeline_layout *layout) { - nir_deref_instr *deref = nir_src_as_deref(instr->src[0]); nir_variable *var = nir_deref_instr_get_variable(deref); - uint32_t set = var->data.descriptor_set; - uint32_t binding = var->data.binding; - struct tu_descriptor_set_layout *set_layout = layout->set[set].layout; - struct tu_descriptor_set_binding_layout *binding_layout = - &set_layout->binding[binding]; + unsigned set = var->data.descriptor_set; + unsigned binding = var->data.binding; + const struct tu_descriptor_set_binding_layout *bind_layout = + &layout->set[set].layout->binding[binding]; + + nir_ssa_def *desc_offset; + unsigned descriptor_stride; + if (bind_layout->type == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) { + unsigned offset = + layout->set[set].input_attachment_start + + bind_layout->input_attachment_offset; + desc_offset = nir_imm_int(b, offset); + set = MAX_SETS; + descriptor_stride = 1; + } else { + unsigned offset = 0; + /* Samplers come second in combined image/sampler descriptors, see + * write_combined_image_sampler_descriptor(). + */ + if (is_sampler && bind_layout->type == + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) { + offset = 1; + } + desc_offset = + nir_imm_int(b, (bind_layout->offset / (4 * A6XX_TEX_CONST_DWORDS)) + + offset); + descriptor_stride = bind_layout->size / (4 * A6XX_TEX_CONST_DWORDS); + } - nir_ssa_def *index = nir_imm_int(b, - map_add(&shader->image_map, - set, binding, var->data.index, - binding_layout->array_size)); if (deref->deref_type != nir_deref_type_var) { assert(deref->deref_type == nir_deref_type_array); - index = nir_iadd(b, index, nir_ssa_for_src(b, deref->arr.index, 1)); + + nir_ssa_def *arr_index = nir_ssa_for_src(b, deref->arr.index, 1); + desc_offset = nir_iadd(b, desc_offset, + nir_imul_imm(b, arr_index, descriptor_stride)); } - nir_rewrite_image_intrinsic(instr, index, false); + + nir_intrinsic_instr *bindless = + nir_intrinsic_instr_create(b->shader, + nir_intrinsic_bindless_resource_ir3); + bindless->num_components = 1; + nir_ssa_dest_init(&bindless->instr, &bindless->dest, + 1, 32, NULL); + nir_intrinsic_set_desc_set(bindless, set); + bindless->src[0] = nir_src_for_ssa(desc_offset); + nir_builder_instr_insert(b, &bindless->instr); + + return &bindless->dest.ssa; +} + +static void +lower_image_deref(nir_builder *b, + nir_intrinsic_instr *instr, struct tu_shader *shader, + const struct tu_pipeline_layout *layout) +{ + nir_deref_instr *deref = nir_src_as_deref(instr->src[0]); + nir_ssa_def *bindless = build_bindless(b, deref, false, shader, layout); + nir_rewrite_image_intrinsic(instr, bindless, true); } static bool @@ -329,9 +265,6 @@ lower_intrinsic(nir_builder *b, nir_intrinsic_instr *instr, case nir_intrinsic_image_deref_atomic_comp_swap: case nir_intrinsic_image_deref_size: case nir_intrinsic_image_deref_samples: - case nir_intrinsic_image_deref_load_param_intel: - case nir_intrinsic_image_deref_load_raw_intel: - case nir_intrinsic_image_deref_store_raw_intel: lower_image_deref(b, instr, shader, layout); return true; @@ -340,6 +273,90 @@ lower_intrinsic(nir_builder *b, nir_intrinsic_instr *instr, } } +static void +lower_tex_ycbcr(const struct tu_pipeline_layout *layout, + nir_builder *builder, + nir_tex_instr *tex) +{ + int deref_src_idx = nir_tex_instr_src_index(tex, nir_tex_src_texture_deref); + assert(deref_src_idx >= 0); + nir_deref_instr *deref = nir_src_as_deref(tex->src[deref_src_idx].src); + + nir_variable *var = nir_deref_instr_get_variable(deref); + const struct tu_descriptor_set_layout *set_layout = + layout->set[var->data.descriptor_set].layout; + const struct tu_descriptor_set_binding_layout *binding = + &set_layout->binding[var->data.binding]; + const struct tu_sampler_ycbcr_conversion *ycbcr_samplers = + tu_immutable_ycbcr_samplers(set_layout, binding); + + if (!ycbcr_samplers) + return; + + /* For the following instructions, we don't apply any change */ + if (tex->op == nir_texop_txs || + tex->op == nir_texop_query_levels || + tex->op == nir_texop_lod) + return; + + assert(tex->texture_index == 0); + unsigned array_index = 0; + if (deref->deref_type != nir_deref_type_var) { + assert(deref->deref_type == nir_deref_type_array); + if (!nir_src_is_const(deref->arr.index)) + return; + array_index = nir_src_as_uint(deref->arr.index); + array_index = MIN2(array_index, binding->array_size - 1); + } + const struct tu_sampler_ycbcr_conversion *ycbcr_sampler = ycbcr_samplers + array_index; + + if (ycbcr_sampler->ycbcr_model == VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY) + return; + + builder->cursor = nir_after_instr(&tex->instr); + + uint8_t bits = vk_format_get_component_bits(ycbcr_sampler->format, + UTIL_FORMAT_COLORSPACE_RGB, + PIPE_SWIZZLE_X); + uint32_t bpcs[3] = {bits, bits, bits}; /* TODO: use right bpc for each channel ? */ + nir_ssa_def *result = nir_convert_ycbcr_to_rgb(builder, + ycbcr_sampler->ycbcr_model, + ycbcr_sampler->ycbcr_range, + &tex->dest.ssa, + bpcs); + nir_ssa_def_rewrite_uses_after(&tex->dest.ssa, nir_src_for_ssa(result), + result->parent_instr); + + builder->cursor = nir_before_instr(&tex->instr); +} + +static bool +lower_tex(nir_builder *b, nir_tex_instr *tex, + struct tu_shader *shader, const struct tu_pipeline_layout *layout) +{ + lower_tex_ycbcr(layout, b, tex); + + int sampler_src_idx = nir_tex_instr_src_index(tex, nir_tex_src_sampler_deref); + if (sampler_src_idx >= 0) { + nir_deref_instr *deref = nir_src_as_deref(tex->src[sampler_src_idx].src); + nir_ssa_def *bindless = build_bindless(b, deref, true, shader, layout); + nir_instr_rewrite_src(&tex->instr, &tex->src[sampler_src_idx].src, + nir_src_for_ssa(bindless)); + tex->src[sampler_src_idx].src_type = nir_tex_src_sampler_handle; + } + + int tex_src_idx = nir_tex_instr_src_index(tex, nir_tex_src_texture_deref); + if (tex_src_idx >= 0) { + nir_deref_instr *deref = nir_src_as_deref(tex->src[tex_src_idx].src); + nir_ssa_def *bindless = build_bindless(b, deref, false, shader, layout); + nir_instr_rewrite_src(&tex->instr, &tex->src[tex_src_idx].src, + nir_src_for_ssa(bindless)); + tex->src[tex_src_idx].src_type = nir_tex_src_texture_handle; + } + + return true; +} + static bool lower_impl(nir_function_impl *impl, struct tu_shader *shader, const struct tu_pipeline_layout *layout) @@ -353,7 +370,7 @@ lower_impl(nir_function_impl *impl, struct tu_shader *shader, b.cursor = nir_before_instr(instr); switch (instr->type) { case nir_instr_type_tex: - progress |= lower_sampler(&b, nir_instr_as_tex(instr), shader, layout); + progress |= lower_tex(&b, nir_instr_as_tex(instr), shader, layout); break; case nir_instr_type_intrinsic: progress |= lower_intrinsic(&b, nir_instr_as_intrinsic(instr), shader, layout); @@ -367,23 +384,102 @@ lower_impl(nir_function_impl *impl, struct tu_shader *shader, return progress; } + +/* Figure out the range of push constants that we're actually going to push to + * the shader, and tell the backend to reserve this range when pushing UBO + * constants. + */ + +static void +gather_push_constants(nir_shader *shader, struct tu_shader *tu_shader) +{ + uint32_t min = UINT32_MAX, max = 0; + nir_foreach_function(function, shader) { + if (!function->impl) + continue; + + nir_foreach_block(block, function->impl) { + nir_foreach_instr_safe(instr, block) { + if (instr->type != nir_instr_type_intrinsic) + continue; + + nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); + if (intrin->intrinsic != nir_intrinsic_load_push_constant) + continue; + + uint32_t base = nir_intrinsic_base(intrin); + uint32_t range = nir_intrinsic_range(intrin); + min = MIN2(min, base); + max = MAX2(max, base + range); + break; + } + } + } + + if (min >= max) { + tu_shader->push_consts.lo = 0; + tu_shader->push_consts.count = 0; + tu_shader->ir3_shader.const_state.num_reserved_user_consts = 0; + return; + } + + /* CP_LOAD_STATE OFFSET and NUM_UNIT are in units of vec4 (4 dwords), + * however there's an alignment requirement of 4 on OFFSET. Expand the + * range and change units accordingly. + */ + tu_shader->push_consts.lo = (min / 16) / 4 * 4; + tu_shader->push_consts.count = + align(max, 16) / 16 - tu_shader->push_consts.lo; + tu_shader->ir3_shader.const_state.num_reserved_user_consts = + align(tu_shader->push_consts.count, 4); +} + +/* Gather the InputAttachmentIndex for each input attachment from the NIR + * shader and organize the info in a way so that draw-time patching is easy. + */ +static void +gather_input_attachments(nir_shader *shader, struct tu_shader *tu_shader, + const struct tu_pipeline_layout *layout) +{ + nir_foreach_variable(var, &shader->uniforms) { + const struct glsl_type *glsl_type = glsl_without_array(var->type); + + if (!glsl_type_is_image(glsl_type)) + continue; + + enum glsl_sampler_dim dim = glsl_get_sampler_dim(glsl_type); + + const uint32_t set = var->data.descriptor_set; + const uint32_t binding = var->data.binding; + const struct tu_descriptor_set_binding_layout *bind_layout = + &layout->set[set].layout->binding[binding]; + const uint32_t array_size = bind_layout->array_size; + + if (dim == GLSL_SAMPLER_DIM_SUBPASS || + dim == GLSL_SAMPLER_DIM_SUBPASS_MS) { + unsigned offset = + layout->set[set].input_attachment_start + + bind_layout->input_attachment_offset; + for (unsigned i = 0; i < array_size; i++) + tu_shader->attachment_idx[offset + i] = var->data.index + i; + } + } +} + static bool tu_lower_io(nir_shader *shader, struct tu_shader *tu_shader, const struct tu_pipeline_layout *layout) { bool progress = false; + gather_push_constants(shader, tu_shader); + gather_input_attachments(shader, tu_shader, layout); + nir_foreach_function(function, shader) { if (function->impl) progress |= lower_impl(function->impl, tu_shader, layout); } - /* spirv_to_nir produces num_ssbos equal to the number of SSBO-containing - * variables, while ir3 wants the number of descriptors (like the gallium - * path). - */ - shader->info.num_ssbos = tu_shader->ssbo_map.num_desc; - return progress; } @@ -436,8 +532,6 @@ tu_shader_create(struct tu_device *dev, struct tu_pipeline_layout *layout, const VkAllocationCallbacks *alloc) { - const struct tu_shader_module *module = - tu_shader_module_from_handle(stage_info->module); struct tu_shader *shader; const uint32_t max_variant_count = (stage == MESA_SHADER_VERTEX) ? 2 : 1; @@ -448,11 +542,25 @@ tu_shader_create(struct tu_device *dev, if (!shader) return NULL; - /* translate SPIR-V to NIR */ - assert(module->code_size % 4 == 0); - nir_shader *nir = tu_spirv_to_nir( - dev->compiler, (const uint32_t *) module->code, module->code_size / 4, - stage, stage_info->pName, stage_info->pSpecializationInfo); + nir_shader *nir; + if (stage_info) { + /* translate SPIR-V to NIR */ + const struct tu_shader_module *module = + tu_shader_module_from_handle(stage_info->module); + assert(module->code_size % 4 == 0); + nir = tu_spirv_to_nir( + dev->compiler, (const uint32_t *) module->code, module->code_size / 4, + stage, stage_info->pName, stage_info->pSpecializationInfo); + } else { + assert(stage == MESA_SHADER_FRAGMENT); + nir_builder fs_b; + const nir_shader_compiler_options *nir_options = + ir3_get_compiler_options(dev->compiler); + nir_builder_init_simple_shader(&fs_b, NULL, MESA_SHADER_FRAGMENT, nir_options); + fs_b.shader->info.name = ralloc_strdup(fs_b.shader, "noop_fs"); + nir = fs_b.shader; + } + if (!nir) { vk_free2(&dev->alloc, alloc, shader); return NULL; @@ -482,7 +590,8 @@ tu_shader_create(struct tu_device *dev, NIR_PASS_V(nir, nir_split_per_member_structs); NIR_PASS_V(nir, nir_remove_dead_variables, - nir_var_shader_in | nir_var_shader_out | nir_var_system_value | nir_var_mem_shared); + nir_var_shader_in | nir_var_shader_out | nir_var_system_value | nir_var_mem_shared, + NULL); /* Gather information for transform feedback. * This should be called after nir_split_per_member_structs. @@ -519,6 +628,9 @@ tu_shader_create(struct tu_device *dev, if (stage == MESA_SHADER_FRAGMENT) NIR_PASS_V(nir, nir_lower_input_attachments, true); + if (stage == MESA_SHADER_GEOMETRY) + NIR_PASS_V(nir, ir3_nir_lower_gs); + NIR_PASS_V(nir, tu_lower_io, shader, layout); NIR_PASS_V(nir, nir_lower_io, nir_var_all, ir3_glsl_type_size, 0); @@ -574,6 +686,7 @@ tu_shader_compile_options_init( const VkGraphicsPipelineCreateInfo *pipeline_info) { bool has_gs = false; + bool msaa = false; if (pipeline_info) { for (uint32_t i = 0; i < pipeline_info->stageCount; i++) { if (pipeline_info->pStages[i].stage == VK_SHADER_STAGE_GEOMETRY_BIT) { @@ -581,12 +694,24 @@ tu_shader_compile_options_init( break; } } + + const VkPipelineMultisampleStateCreateInfo *msaa_info = pipeline_info->pMultisampleState; + const struct VkPipelineSampleLocationsStateCreateInfoEXT *sample_locations = + vk_find_struct_const(msaa_info->pNext, PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT); + if (!pipeline_info->pRasterizationState->rasterizerDiscardEnable && + (msaa_info->rasterizationSamples > 1 || + /* also set msaa key when sample location is not the default + * since this affects varying interpolation */ + (sample_locations && sample_locations->sampleLocationsEnable))) { + msaa = true; + } } *options = (struct tu_shader_compile_options) { /* TODO: Populate the remaining fields of ir3_shader_key. */ .key = { .has_gs = has_gs, + .msaa = msaa, }, /* TODO: VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT * some optimizations need to happen otherwise shader might not compile @@ -641,6 +766,14 @@ tu_shader_compile(struct tu_device *dev, if (!shader->binary) return VK_ERROR_OUT_OF_HOST_MEMORY; + if (shader_debug_enabled(shader->ir3_shader.type)) { + fprintf(stdout, "Native code for unnamed %s shader %s:\n", + ir3_shader_stage(&shader->variants[0]), shader->ir3_shader.nir->info.name); + if (shader->ir3_shader.type == MESA_SHADER_FRAGMENT) + fprintf(stdout, "SIMD0\n"); + ir3_shader_disasm(&shader->variants[0], shader->binary, stdout); + } + /* compile another variant for the binning pass */ if (options->include_binning_pass && shader->ir3_shader.type == MESA_SHADER_VERTEX) { @@ -651,6 +784,12 @@ tu_shader_compile(struct tu_device *dev, return VK_ERROR_OUT_OF_HOST_MEMORY; shader->has_binning_pass = true; + + if (shader_debug_enabled(MESA_SHADER_VERTEX)) { + fprintf(stdout, "Native code for unnamed binning shader %s:\n", + shader->ir3_shader.nir->info.name); + ir3_shader_disasm(&shader->variants[1], shader->binary, stdout); + } } if (unlikely(dev->physical_device->instance->debug_flags & TU_DEBUG_IR3)) {