#include "util/mesa-sha1.h"
#include "common/gen_l3_config.h"
#include "anv_private.h"
-#include "brw_nir.h"
+#include "compiler/brw_nir.h"
#include "anv_nir.h"
#include "spirv/nir_spirv.h"
* we can't do that yet because we don't have the ability to copy nir.
*/
static nir_shader *
-anv_shader_compile_to_nir(struct anv_device *device,
+anv_shader_compile_to_nir(struct anv_pipeline *pipeline,
struct anv_shader_module *module,
const char *entrypoint_name,
gl_shader_stage stage,
const VkSpecializationInfo *spec_info)
{
- if (strcmp(entrypoint_name, "main") != 0) {
- anv_finishme("Multiple shaders per module not really supported");
- }
+ const struct anv_device *device = pipeline->device;
const struct brw_compiler *compiler =
device->instance->physicalDevice.compiler;
const struct nir_spirv_supported_extensions supported_ext = {
.float64 = device->instance->physicalDevice.info.gen >= 8,
+ .int64 = device->instance->physicalDevice.info.gen >= 8,
.tessellation = true,
+ .draw_parameters = true,
+ .image_write_without_format = true,
};
nir_function *entry_point =
nir_var_shader_in | nir_var_shader_out | nir_var_system_value);
if (stage == MESA_SHADER_FRAGMENT)
- NIR_PASS_V(nir, nir_lower_wpos_center);
+ NIR_PASS_V(nir, nir_lower_wpos_center, pipeline->sample_shading_enable);
/* Now that we've deleted all but the main function, we can go ahead and
* lower the rest of the constant initializers.
if (stage == MESA_SHADER_FRAGMENT)
NIR_PASS_V(nir, anv_nir_lower_input_attachments);
- nir_shader_gather_info(nir, entry_point->impl);
-
return nir;
}
populate_sampler_prog_key(const struct gen_device_info *devinfo,
struct brw_sampler_prog_key_data *key)
{
+ /* Almost all multisampled textures are compressed. The only time when we
+ * don't compress a multisampled texture is for 16x MSAA with a surface
+ * width greater than 8k which is a bit of an edge case. Since the sampler
+ * just ignores the MCS parameter to ld2ms when MCS is disabled, it's safe
+ * to tell the compiler to always assume compression.
+ */
+ key->compressed_multisample_layout_mask = ~0;
+
+ /* SkyLake added support for 16x MSAA. With this came a new message for
+ * reading from a 16x MSAA surface with compression. The new message was
+ * needed because now the MCS data is 64 bits instead of 32 or lower as is
+ * the case for 8x, 4x, and 2x. The key->msaa_16 bit-field controls which
+ * message we use. Fortunately, the 16x message works for 8x, 4x, and 2x
+ * so we can just use it unconditionally. This may not be quite as
+ * efficient but it saves us from recompiling.
+ */
+ if (devinfo->gen >= 9)
+ key->msaa_16 = ~0;
+
/* XXX: Handle texture swizzle on HSW- */
for (int i = 0; i < MAX_SAMPLERS; i++) {
/* Assume color sampler, no swizzling. (Works for BDW+) */
/* TODO: we could set this to 0 based on the information in nir_shader, but
* this function is called before spirv_to_nir. */
const struct brw_vue_map *vue_map =
- anv_pipeline_get_fs_input_map(pipeline);
+ &anv_pipeline_get_last_vue_prog_data(pipeline)->vue_map;
key->input_slots_valid = vue_map->slots_valid;
/* Vulkan doesn't specify a default */
info->pMultisampleState &&
info->pMultisampleState->alphaToCoverageEnable;
- if (info->pMultisampleState && info->pMultisampleState->rasterizationSamples > 1) {
+ if (info->pMultisampleState) {
/* We should probably pull this out of the shader, but it's fairly
* harmless to compute it and then let dead-code take care of it.
*/
- key->persample_interp =
- (info->pMultisampleState->minSampleShading *
- info->pMultisampleState->rasterizationSamples) > 1;
- key->multisample_fbo = true;
+ if (info->pMultisampleState->rasterizationSamples > 1) {
+ key->persample_interp =
+ (info->pMultisampleState->minSampleShading *
+ info->pMultisampleState->rasterizationSamples) > 1;
+ key->multisample_fbo = true;
+ }
+
+ key->frag_coord_adds_sample_pos =
+ info->pMultisampleState->sampleShadingEnable;
}
}
populate_sampler_prog_key(devinfo, &key->tex);
}
+static void
+anv_pipeline_hash_shader(struct anv_pipeline *pipeline,
+ struct anv_shader_module *module,
+ const char *entrypoint,
+ gl_shader_stage stage,
+ const VkSpecializationInfo *spec_info,
+ const void *key, size_t key_size,
+ unsigned char *sha1_out)
+{
+ struct mesa_sha1 ctx;
+
+ _mesa_sha1_init(&ctx);
+ if (pipeline->layout) {
+ _mesa_sha1_update(&ctx, pipeline->layout->sha1,
+ sizeof(pipeline->layout->sha1));
+ }
+ _mesa_sha1_update(&ctx, module->sha1, sizeof(module->sha1));
+ _mesa_sha1_update(&ctx, entrypoint, strlen(entrypoint));
+ _mesa_sha1_update(&ctx, &stage, sizeof(stage));
+ if (spec_info) {
+ _mesa_sha1_update(&ctx, spec_info->pMapEntries,
+ spec_info->mapEntryCount * sizeof(*spec_info->pMapEntries));
+ _mesa_sha1_update(&ctx, spec_info->pData, spec_info->dataSize);
+ }
+ _mesa_sha1_update(&ctx, key, key_size);
+ _mesa_sha1_final(&ctx, sha1_out);
+}
+
static nir_shader *
anv_pipeline_compile(struct anv_pipeline *pipeline,
struct anv_shader_module *module,
struct brw_stage_prog_data *prog_data,
struct anv_pipeline_bind_map *map)
{
- nir_shader *nir = anv_shader_compile_to_nir(pipeline->device,
+ nir_shader *nir = anv_shader_compile_to_nir(pipeline,
module, entrypoint, stage,
spec_info);
if (nir == NULL)
NIR_PASS_V(nir, anv_nir_lower_push_constants);
+ nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
+
/* Figure out the number of parameters */
prog_data->nr_params = 0;
prog_data->nr_params += MAX_PUSH_CONSTANTS_SIZE / sizeof(float);
}
- if (pipeline->layout && pipeline->layout->stage[stage].has_dynamic_offsets)
- prog_data->nr_params += MAX_DYNAMIC_BUFFERS * 2;
-
if (nir->info->num_images > 0) {
prog_data->nr_params += nir->info->num_images * BRW_IMAGE_PARAM_SIZE;
pipeline->needs_data_cache = true;
}
}
- /* Set up dynamic offsets */
- anv_nir_apply_dynamic_offsets(pipeline, nir, prog_data);
-
/* Apply the actual pipeline layout to UBOs, SSBOs, and textures */
if (pipeline->layout)
anv_nir_apply_pipeline_layout(pipeline, nir, prog_data, map);
populate_vs_prog_key(&pipeline->device->info, &key);
if (cache) {
- anv_hash_shader(sha1, &key, sizeof(key), module, entrypoint,
- pipeline->layout, spec_info);
+ anv_pipeline_hash_shader(pipeline, module, entrypoint,
+ MESA_SHADER_VERTEX, spec_info,
+ &key, sizeof(key), sha1);
bin = anv_pipeline_cache_search(cache, sha1, 20);
}
tcs_key.input_vertices = info->pTessellationState->patchControlPoints;
if (cache) {
- anv_hash_shader(tcs_sha1, &tcs_key, sizeof(tcs_key), tcs_module,
- tcs_entrypoint, pipeline->layout, tcs_spec_info);
- anv_hash_shader(tes_sha1, &tes_key, sizeof(tes_key), tes_module,
- tes_entrypoint, pipeline->layout, tes_spec_info);
+ anv_pipeline_hash_shader(pipeline, tcs_module, tcs_entrypoint,
+ MESA_SHADER_TESS_CTRL, tcs_spec_info,
+ &tcs_key, sizeof(tcs_key), tcs_sha1);
+ anv_pipeline_hash_shader(pipeline, tes_module, tes_entrypoint,
+ MESA_SHADER_TESS_EVAL, tes_spec_info,
+ &tes_key, sizeof(tes_key), tes_sha1);
memcpy(&tcs_sha1[20], tes_sha1, 20);
memcpy(&tes_sha1[20], tcs_sha1, 20);
tcs_bin = anv_pipeline_cache_search(cache, tcs_sha1, sizeof(tcs_sha1));
populate_gs_prog_key(&pipeline->device->info, &key);
if (cache) {
- anv_hash_shader(sha1, &key, sizeof(key), module, entrypoint,
- pipeline->layout, spec_info);
+ anv_pipeline_hash_shader(pipeline, module, entrypoint,
+ MESA_SHADER_GEOMETRY, spec_info,
+ &key, sizeof(key), sha1);
bin = anv_pipeline_cache_search(cache, sha1, 20);
}
populate_wm_prog_key(pipeline, info, &key);
if (cache) {
- anv_hash_shader(sha1, &key, sizeof(key), module, entrypoint,
- pipeline->layout, spec_info);
+ anv_pipeline_hash_shader(pipeline, module, entrypoint,
+ MESA_SHADER_FRAGMENT, spec_info,
+ &key, sizeof(key), sha1);
bin = anv_pipeline_cache_search(cache, sha1, 20);
}
populate_cs_prog_key(&pipeline->device->info, &key);
if (cache) {
- anv_hash_shader(sha1, &key, sizeof(key), module, entrypoint,
- pipeline->layout, spec_info);
+ anv_pipeline_hash_shader(pipeline, module, entrypoint,
+ MESA_SHADER_COMPUTE, spec_info,
+ &key, sizeof(key), sha1);
bin = anv_pipeline_cache_search(cache, sha1, 20);
}
*/
bool uses_color_att = false;
for (unsigned i = 0; i < subpass->color_count; ++i) {
- if (subpass->color_attachments[i] != VK_ATTACHMENT_UNUSED) {
+ if (subpass->color_attachments[i].attachment != VK_ATTACHMENT_UNUSED) {
uses_color_att = true;
break;
}
* against does not use a depth/stencil attachment.
*/
if (!pCreateInfo->pRasterizationState->rasterizerDiscardEnable &&
- subpass->depth_stencil_attachment != VK_ATTACHMENT_UNUSED) {
+ subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED) {
assert(pCreateInfo->pDepthStencilState);
if (states & (1 << VK_DYNAMIC_STATE_DEPTH_BOUNDS)) {
static void
anv_pipeline_validate_create_info(const VkGraphicsPipelineCreateInfo *info)
{
+#ifdef DEBUG
struct anv_render_pass *renderpass = NULL;
struct anv_subpass *subpass = NULL;
assert(info->pViewportState);
assert(info->pMultisampleState);
- if (subpass && subpass->depth_stencil_attachment != VK_ATTACHMENT_UNUSED)
+ if (subpass && subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED)
assert(info->pDepthStencilState);
if (subpass && subpass->color_count > 0)
break;
}
}
+#endif
}
/**
{
VkResult result;
- anv_validate {
- anv_pipeline_validate_create_info(pCreateInfo);
- }
+ anv_pipeline_validate_create_info(pCreateInfo);
if (alloc == NULL)
alloc = &device->alloc;
pipeline->batch.next = pipeline->batch.start = pipeline->batch_data;
pipeline->batch.end = pipeline->batch.start + sizeof(pipeline->batch_data);
pipeline->batch.relocs = &pipeline->batch_relocs;
+ pipeline->batch.status = VK_SUCCESS;
copy_non_dynamic_state(pipeline, pCreateInfo);
pipeline->depth_clamp_enable = pCreateInfo->pRasterizationState &&
pCreateInfo->pRasterizationState->depthClampEnable;
+ pipeline->sample_shading_enable = pCreateInfo->pMultisampleState &&
+ pCreateInfo->pMultisampleState->sampleShadingEnable;
+
pipeline->needs_data_cache = false;
/* When we free the pipeline, we detect stages based on the NULL status