#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"
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;
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;
}
&set_layout->binding[binding];
uint32_t base;
+ shader->active_desc_sets |= 1u << set;
+
switch (binding_layout->type) {
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
const struct tu_descriptor_set_binding_layout *bind_layout =
&layout->set[set].layout->binding[binding];
+ shader->active_desc_sets |= 1u << set;
+
nir_ssa_def *desc_offset;
unsigned descriptor_stride;
if (bind_layout->type == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) {
}
}
+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);
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;
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;
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.
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);
}
}
+ 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 &&
- pipeline_info->pMultisampleState->rasterizationSamples > 1)
+ (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) {
if (ret)
return NULL;
+ /* num_samp should be 0 for bindless, but we use it with blit shader */
+ variant->num_samp = 0;
+
/* when assemble fails, we rely on tu_shader_destroy to clean up the
* variant
*/