#include "common/gen_l3_config.h"
#include "common/gen_sample_positions.h"
+#include "vk_util.h"
#include "vk_format_info.h"
static uint32_t
const uint32_t elements_double = double_inputs_read >> VERT_ATTRIB_GENERIC0;
const bool needs_svgs_elem = vs_prog_data->uses_vertexid ||
vs_prog_data->uses_instanceid ||
- vs_prog_data->uses_basevertex ||
+ vs_prog_data->uses_firstvertex ||
vs_prog_data->uses_baseinstance;
uint32_t elem_count = __builtin_popcount(elements) -
struct GENX(VERTEX_ELEMENT_STATE) element = {
.VertexBufferIndex = desc->binding,
.Valid = true,
- .SourceElementFormat = (enum GENX(SURFACE_FORMAT)) format,
+ .SourceElementFormat = format,
.EdgeFlagEnable = false,
.SourceElementOffset = desc->offset,
.Component0Control = vertex_element_comp_control(format, 0),
anv_batch_emit(&pipeline->batch, GENX(3DSTATE_VF_INSTANCING), vfi) {
vfi.InstancingEnable = pipeline->instancing_enable[desc->binding];
vfi.VertexElementIndex = slot;
- /* Our implementation of VK_KHX_multiview uses instancing to draw
+ /* Our implementation of VK_KHR_multiview uses instancing to draw
* the different views. If the client asks for instancing, we
* need to use the Instance Data Step Rate to ensure that we
* repeat the client's per-instance data once for each view.
* This means, that if we have BaseInstance, we need BaseVertex as
* well. Just do all or nothing.
*/
- uint32_t base_ctrl = (vs_prog_data->uses_basevertex ||
+ uint32_t base_ctrl = (vs_prog_data->uses_firstvertex ||
vs_prog_data->uses_baseinstance) ?
VFCOMP_STORE_SRC : VFCOMP_STORE_0;
struct GENX(VERTEX_ELEMENT_STATE) element = {
.VertexBufferIndex = ANV_SVGS_VB_INDEX,
.Valid = true,
- .SourceElementFormat = (enum GENX(SURFACE_FORMAT)) ISL_FORMAT_R32G32_UINT,
+ .SourceElementFormat = ISL_FORMAT_R32G32_UINT,
.Component0Control = base_ctrl,
.Component1Control = base_ctrl,
#if GEN_GEN >= 8
struct GENX(VERTEX_ELEMENT_STATE) element = {
.VertexBufferIndex = ANV_DRAWID_VB_INDEX,
.Valid = true,
- .SourceElementFormat = (enum GENX(SURFACE_FORMAT)) ISL_FORMAT_R32_UINT,
+ .SourceElementFormat = ISL_FORMAT_R32_UINT,
.Component0Control = VFCOMP_STORE_SRC,
.Component1Control = VFCOMP_STORE_0,
.Component2Control = VFCOMP_STORE_0,
/* We have to subtract two slots to accout for the URB entry output
* read offset in the VS and GS stages.
*/
- assert(slot >= 2);
const int source_attr = slot - 2 * urb_entry_read_offset;
+ assert(source_attr >= 0 && source_attr < 32);
max_source_attr = MAX2(max_source_attr, source_attr);
swiz.Attribute[input_index].SourceAttribute = source_attr;
}
static uint32_t
get_sampler_count(const struct anv_shader_bin *bin)
{
- return DIV_ROUND_UP(bin->bind_map.sampler_count, 4);
+ uint32_t count_by_4 = DIV_ROUND_UP(bin->bind_map.sampler_count, 4);
+
+ /* We can potentially have way more than 32 samplers and that's ok.
+ * However, the 3DSTATE_XS packets only have 3 bits to specify how
+ * many to pre-fetch and all values above 4 are marked reserved.
+ */
+ return MIN2(count_by_4, 4);
}
static uint32_t
return ffs(bin->prog_data->total_scratch / 2048);
}
-static uint32_t
-get_urb_output_offset()
-{
- /* Skip the VUE header and position slots */
- return 1;
-}
-
-UNUSED static uint32_t
-get_urb_output_length(const struct anv_shader_bin *bin)
-{
- const struct brw_vue_prog_data *prog_data =
- (const struct brw_vue_prog_data *)bin->prog_data;
-
- return (prog_data->vue_map.num_slots + 1) / 2 - get_urb_output_offset();
-}
-
static void
emit_3dstate_vs(struct anv_pipeline *pipeline)
{
#endif
assert(!vs_prog_data->base.base.use_alt_mode);
+#if GEN_GEN < 11
vs.SingleVertexDispatch = false;
+#endif
vs.VectorMaskEnable = false;
vs.SamplerCount = get_sampler_count(vs_bin);
vs.BindingTableEntryCount = get_binding_table_entry_count(vs_bin);
vs_prog_data->base.base.dispatch_grf_start_reg;
#if GEN_GEN >= 8
- vs.VertexURBEntryOutputReadOffset = get_urb_output_offset();
- vs.VertexURBEntryOutputLength = get_urb_output_length(vs_bin);
-
vs.UserClipDistanceClipTestEnableBitmask =
vs_prog_data->base.clip_distance_mask;
vs.UserClipDistanceCullTestEnableBitmask =
}
static void
-emit_3dstate_hs_te_ds(struct anv_pipeline *pipeline)
+emit_3dstate_hs_te_ds(struct anv_pipeline *pipeline,
+ const VkPipelineTessellationStateCreateInfo *tess_info)
{
if (!anv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_EVAL)) {
anv_batch_emit(&pipeline->batch, GENX(3DSTATE_HS), hs);
get_scratch_address(pipeline, MESA_SHADER_TESS_CTRL, tcs_bin);
}
+ const VkPipelineTessellationDomainOriginStateCreateInfoKHR *domain_origin_state =
+ tess_info ? vk_find_struct_const(tess_info, PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO_KHR) : NULL;
+
+ VkTessellationDomainOriginKHR uv_origin =
+ domain_origin_state ? domain_origin_state->domainOrigin :
+ VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT_KHR;
+
anv_batch_emit(&pipeline->batch, GENX(3DSTATE_TE), te) {
te.Partitioning = tes_prog_data->partitioning;
- te.OutputTopology = tes_prog_data->output_topology;
+
+ if (uv_origin == VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT_KHR) {
+ te.OutputTopology = tes_prog_data->output_topology;
+ } else {
+ /* When the origin is upper-left, we have to flip the winding order */
+ if (tes_prog_data->output_topology == OUTPUT_TRI_CCW) {
+ te.OutputTopology = OUTPUT_TRI_CW;
+ } else if (tes_prog_data->output_topology == OUTPUT_TRI_CW) {
+ te.OutputTopology = OUTPUT_TRI_CCW;
+ } else {
+ te.OutputTopology = tes_prog_data->output_topology;
+ }
+ }
+
te.TEDomain = tes_prog_data->domain;
te.TEEnable = true;
te.MaximumTessellationFactorOdd = 63.0;
tes_prog_data->base.base.dispatch_grf_start_reg;
#if GEN_GEN >= 8
- ds.VertexURBEntryOutputReadOffset = 1;
- ds.VertexURBEntryOutputLength =
- (tes_prog_data->base.vue_map.num_slots + 1) / 2 - 1;
-
+#if GEN_GEN < 11
ds.DispatchMode =
tes_prog_data->base.dispatch_mode == DISPATCH_MODE_SIMD8 ?
DISPATCH_MODE_SIMD8_SINGLE_PATCH :
DISPATCH_MODE_SIMD4X2;
+#else
+ assert(tes_prog_data->base.dispatch_mode == DISPATCH_MODE_SIMD8);
+ ds.DispatchMode = DISPATCH_MODE_SIMD8_SINGLE_PATCH;
+#endif
ds.UserClipDistanceClipTestEnableBitmask =
tes_prog_data->base.clip_distance_mask;
gs_prog_data->base.base.dispatch_grf_start_reg;
#if GEN_GEN >= 8
- gs.VertexURBEntryOutputReadOffset = get_urb_output_offset();
- gs.VertexURBEntryOutputLength = get_urb_output_length(gs_bin);
-
gs.UserClipDistanceClipTestEnableBitmask =
gs_prog_data->base.clip_distance_mask;
gs.UserClipDistanceCullTestEnableBitmask =
}
static bool
-has_color_buffer_write_enabled(const struct anv_pipeline *pipeline)
+has_color_buffer_write_enabled(const struct anv_pipeline *pipeline,
+ const VkPipelineColorBlendStateCreateInfo *blend)
{
const struct anv_shader_bin *shader_bin =
pipeline->shaders[MESA_SHADER_FRAGMENT];
const struct anv_pipeline_bind_map *bind_map = &shader_bin->bind_map;
for (int i = 0; i < bind_map->surface_count; i++) {
- if (bind_map->surface_to_descriptor[i].set !=
- ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS)
+ struct anv_pipeline_binding *binding = &bind_map->surface_to_descriptor[i];
+
+ if (binding->set != ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS)
+ continue;
+
+ if (binding->index == UINT32_MAX)
continue;
- if (bind_map->surface_to_descriptor[i].index != UINT32_MAX)
+
+ if (blend && blend->pAttachments[binding->index].colorWriteMask != 0)
return true;
}
static void
emit_3dstate_wm(struct anv_pipeline *pipeline, struct anv_subpass *subpass,
+ const VkPipelineColorBlendStateCreateInfo *blend,
const VkPipelineMultisampleStateCreateInfo *multisample)
{
const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline);
if (wm.PixelShaderComputedDepthMode != PSCDEPTH_OFF ||
wm_prog_data->has_side_effects ||
wm.PixelShaderKillsPixel ||
- has_color_buffer_write_enabled(pipeline))
+ has_color_buffer_write_enabled(pipeline, blend))
wm.ThreadDispatchEnable = true;
if (samples > 1) {
#endif
anv_batch_emit(&pipeline->batch, GENX(3DSTATE_PS), ps) {
- ps.KernelStartPointer0 = fs_bin->kernel.offset;
- ps.KernelStartPointer1 = 0;
- ps.KernelStartPointer2 = fs_bin->kernel.offset +
- wm_prog_data->prog_offset_2;
ps._8PixelDispatchEnable = wm_prog_data->dispatch_8;
ps._16PixelDispatchEnable = wm_prog_data->dispatch_16;
- ps._32PixelDispatchEnable = false;
+ ps._32PixelDispatchEnable = wm_prog_data->dispatch_32;
+
+ ps.KernelStartPointer0 = fs_bin->kernel.offset +
+ brw_wm_prog_data_prog_offset(wm_prog_data, ps, 0);
+ ps.KernelStartPointer1 = fs_bin->kernel.offset +
+ brw_wm_prog_data_prog_offset(wm_prog_data, ps, 1);
+ ps.KernelStartPointer2 = fs_bin->kernel.offset +
+ brw_wm_prog_data_prog_offset(wm_prog_data, ps, 2);
ps.SingleProgramFlow = false;
ps.VectorMaskEnable = true;
ps.SamplerCount = get_sampler_count(fs_bin);
ps.BindingTableEntryCount = get_binding_table_entry_count(fs_bin);
- ps.PushConstantEnable = wm_prog_data->base.nr_params > 0;
+ ps.PushConstantEnable = wm_prog_data->base.nr_params > 0 ||
+ wm_prog_data->base.ubo_ranges[0].length;
ps.PositionXYOffsetSelect = wm_prog_data->uses_pos_offset ?
POSOFFSET_SAMPLE: POSOFFSET_NONE;
#if GEN_GEN < 8
#endif
ps.DispatchGRFStartRegisterForConstantSetupData0 =
- wm_prog_data->base.dispatch_grf_start_reg;
- ps.DispatchGRFStartRegisterForConstantSetupData1 = 0;
+ brw_wm_prog_data_dispatch_grf_start_reg(wm_prog_data, ps, 0);
+ ps.DispatchGRFStartRegisterForConstantSetupData1 =
+ brw_wm_prog_data_dispatch_grf_start_reg(wm_prog_data, ps, 1);
ps.DispatchGRFStartRegisterForConstantSetupData2 =
- wm_prog_data->dispatch_grf_start_reg_2;
+ brw_wm_prog_data_dispatch_grf_start_reg(wm_prog_data, ps, 2);
ps.PerThreadScratchSpace = get_scratch_space(fs_bin);
ps.ScratchSpaceBasePointer =
#if GEN_GEN >= 8
static void
emit_3dstate_ps_extra(struct anv_pipeline *pipeline,
- struct anv_subpass *subpass)
+ struct anv_subpass *subpass,
+ const VkPipelineColorBlendStateCreateInfo *blend)
{
const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline);
* attachments, we need to force-enable here.
*/
if ((wm_prog_data->has_side_effects || wm_prog_data->uses_kill) &&
- !has_color_buffer_write_enabled(pipeline))
+ !has_color_buffer_write_enabled(pipeline, blend))
ps.PixelShaderHasUAV = true;
#if GEN_GEN >= 9
+ ps.PixelShaderComputesStencil = wm_prog_data->computed_stencil;
ps.PixelShaderPullsBary = wm_prog_data->pulls_bary;
ps.InputCoverageMaskState = wm_prog_data->uses_sample_mask ?
ICMS_INNER_CONSERVATIVE : ICMS_NONE;
* whole fixed function pipeline" means to emit a PIPE_CONTROL with the "CS
* Stall" bit set.
*/
- if (!brw->is_haswell && !brw->is_baytrail)
+ if (!device->info.is_haswell && !device->info.is_baytrail)
gen7_emit_vs_workaround_flush(brw);
#endif
emit_3dstate_vs(pipeline);
- emit_3dstate_hs_te_ds(pipeline);
+ emit_3dstate_hs_te_ds(pipeline, pCreateInfo->pTessellationState);
emit_3dstate_gs(pipeline);
emit_3dstate_sbe(pipeline);
- emit_3dstate_wm(pipeline, subpass, pCreateInfo->pMultisampleState);
+ emit_3dstate_wm(pipeline, subpass, pCreateInfo->pColorBlendState,
+ pCreateInfo->pMultisampleState);
emit_3dstate_ps(pipeline, pCreateInfo->pColorBlendState);
#if GEN_GEN >= 8
- emit_3dstate_ps_extra(pipeline, subpass);
+ emit_3dstate_ps_extra(pipeline, subpass, pCreateInfo->pColorBlendState);
emit_3dstate_vf_topology(pipeline);
#endif
emit_3dstate_vf_statistics(pipeline);
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
pipeline->device = device;
- pipeline->layout = anv_pipeline_layout_from_handle(pCreateInfo->layout);
pipeline->blend_state.map = NULL;
pipeline->needs_data_cache = false;
assert(pCreateInfo->stage.stage == VK_SHADER_STAGE_COMPUTE_BIT);
+ pipeline->active_stages |= VK_SHADER_STAGE_COMPUTE_BIT;
ANV_FROM_HANDLE(anv_shader_module, module, pCreateInfo->stage.module);
result = anv_pipeline_compile_cs(pipeline, cache, pCreateInfo, module,
pCreateInfo->stage.pName,
vfe.MaximumNumberofThreads =
devinfo->max_cs_threads * subslices - 1;
vfe.NumberofURBEntries = GEN_GEN <= 7 ? 0 : 2;
+#if GEN_GEN < 11
vfe.ResetGatewayTimer = true;
+#endif
#if GEN_GEN <= 8
vfe.BypassGatewayControl = true;
#endif