diff --git a/src/microsoft/spirv_to_dxil/spirv_to_dxil.h b/src/microsoft/spirv_to_dxil/spirv_to_dxil.h index 40adf761ef5..a4baa61857a 100644 --- a/src/microsoft/spirv_to_dxil/spirv_to_dxil.h +++ b/src/microsoft/spirv_to_dxil/spirv_to_dxil.h @@ -120,6 +120,10 @@ struct dxil_spirv_vertex_runtime_data { float viewport_width; float viewport_height; uint32_t view_index; + /* When depth bias is dynamic, the constant value to add to point + * primitives when emulating triangle point fill mode. Slope-scaled + * depth bias is currently unsupported. */ + float depth_bias; }; enum dxil_spirv_yz_flip_mode { diff --git a/src/microsoft/vulkan/dzn_cmd_buffer.c b/src/microsoft/vulkan/dzn_cmd_buffer.c index 794f2111bf6..865fcd6e607 100644 --- a/src/microsoft/vulkan/dzn_cmd_buffer.c +++ b/src/microsoft/vulkan/dzn_cmd_buffer.c @@ -3128,6 +3128,9 @@ dzn_cmd_buffer_update_pipeline(struct dzn_cmd_buffer *cmdbuf, uint32_t bindpoint ID3D12GraphicsCommandList1_SetViewInstanceMask(cmdbuf->cmdlist, gfx->multiview.view_mask); else ID3D12GraphicsCommandList1_SetViewInstanceMask(cmdbuf->cmdlist, 1); + + if (gfx->zsa.dynamic_depth_bias && gfx->use_gs_for_polygon_mode_point) + cmdbuf->state.bindpoint[bindpoint].dirty |= DZN_CMD_BINDPOINT_DIRTY_SYSVALS; } } @@ -5692,6 +5695,7 @@ dzn_CmdSetDepthBias(VkCommandBuffer commandBuffer, cmdbuf->state.pipeline_variant.depth_bias.constant_factor = depthBiasConstantFactor; cmdbuf->state.pipeline_variant.depth_bias.clamp = depthBiasClamp; cmdbuf->state.pipeline_variant.depth_bias.slope_factor = depthBiasSlopeFactor; + cmdbuf->state.sysvals.gfx.depth_bias = depthBiasConstantFactor; if (pdev->options16.DynamicDepthBiasSupported) cmdbuf->state.dirty |= DZN_CMD_DIRTY_DEPTH_BIAS; else diff --git a/src/microsoft/vulkan/dzn_nir.c b/src/microsoft/vulkan/dzn_nir.c index 0c2b31602fd..2945bd84645 100644 --- a/src/microsoft/vulkan/dzn_nir.c +++ b/src/microsoft/vulkan/dzn_nir.c @@ -28,6 +28,7 @@ #include "nir_builder.h" #include "nir_builtin_builder.h" #include "nir_vulkan.h" +#include "dxil_nir.h" static nir_ssa_def * dzn_nir_create_bo_desc(nir_builder *b, @@ -784,8 +785,33 @@ copy_vars(nir_builder *b, nir_deref_instr *dst, nir_deref_instr *src) } } +static nir_ssa_def * +load_dynamic_depth_bias(nir_builder *b, struct dzn_nir_point_gs_info *info) +{ + nir_address_format ubo_format = nir_address_format_32bit_index_offset; + unsigned offset = offsetof(struct dxil_spirv_vertex_runtime_data, depth_bias); + + nir_ssa_def *index = nir_vulkan_resource_index( + b, nir_address_format_num_components(ubo_format), + nir_address_format_bit_size(ubo_format), + nir_imm_int(b, 0), + .desc_set = info->runtime_data_cbv.register_space, + .binding = info->runtime_data_cbv.base_shader_register, + .desc_type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); + + nir_ssa_def *load_desc = nir_load_vulkan_descriptor( + b, nir_address_format_num_components(ubo_format), + nir_address_format_bit_size(ubo_format), + index, .desc_type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); + + return build_load_ubo_dxil( + b, nir_channel(b, load_desc, 0), + nir_imm_int(b, offset), + 1, 32, 4); +} + nir_shader * -dzn_nir_polygon_point_mode_gs(const nir_shader *previous_shader, unsigned cull_mode, bool front_ccw) +dzn_nir_polygon_point_mode_gs(const nir_shader *previous_shader, struct dzn_nir_point_gs_info *info) { nir_builder builder; nir_builder *b = &builder; @@ -838,6 +864,33 @@ dzn_nir_polygon_point_mode_gs(const nir_shader *previous_shader, unsigned cull_m front_facing_var->data.driver_location = num_vars; front_facing_var->data.interpolation = INTERP_MODE_FLAT; + nir_ssa_def *depth_bias_scale = NULL; + if (info->depth_bias) { + switch (info->ds_fmt) { + case DXGI_FORMAT_D16_UNORM: + depth_bias_scale = nir_imm_float(b, 1.0f / (1 << 16)); + break; + case DXGI_FORMAT_D24_UNORM_S8_UINT: + depth_bias_scale = nir_imm_float(b, 1.0f / (1 << 24)); + break; + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: { + nir_deref_instr *deref_pos = nir_build_deref_var(b, pos_var); + nir_ssa_def *max_z = NULL; + for (uint32_t i = 0; i < 3; ++i) { + nir_ssa_def *pos = nir_load_deref(b, nir_build_deref_array_imm(b, deref_pos, i)); + nir_ssa_def *z = nir_iand_imm(b, nir_channel(b, pos, 2), 0x7fffffff); + max_z = i == 0 ? z : nir_imax(b, z, max_z); + } + nir_ssa_def *exponent = nir_ishr_imm(b, nir_iand_imm(b, max_z, 0x7f800000), 23); + depth_bias_scale = nir_fexp2(b, nir_i2f32(b, nir_iadd_imm(b, exponent, -23))); + break; + } + default: + depth_bias_scale = nir_imm_float(b, 0.0f); + } + } + /* Temporary variable "loop_index" to loop over input vertices */ nir_function_impl *impl = nir_shader_get_entrypoint(nir); nir_variable *loop_index_var = @@ -847,15 +900,15 @@ dzn_nir_polygon_point_mode_gs(const nir_shader *previous_shader, unsigned cull_m nir_ssa_def *cull_pass = nir_imm_bool(b, true); nir_ssa_def *front_facing; - assert(cull_mode != VK_CULL_MODE_FRONT_AND_BACK); - if (cull_mode == VK_CULL_MODE_FRONT_BIT) { - cull_pass = cull_face(b, pos_var, front_ccw); + assert(info->cull_mode != VK_CULL_MODE_FRONT_AND_BACK); + if (info->cull_mode == VK_CULL_MODE_FRONT_BIT) { + cull_pass = cull_face(b, pos_var, info->front_ccw); front_facing = nir_b2i32(b, cull_pass); - } else if (cull_mode == VK_CULL_MODE_BACK_BIT) { - cull_pass = cull_face(b, pos_var, !front_ccw); + } else if (info->cull_mode == VK_CULL_MODE_BACK_BIT) { + cull_pass = cull_face(b, pos_var, !info->front_ccw); front_facing = nir_inot(b, nir_b2i32(b, cull_pass)); } else - front_facing = nir_i2i32(b, cull_face(b, pos_var, front_ccw)); + front_facing = nir_i2i32(b, cull_face(b, pos_var, info->front_ccw)); /** * if (cull_pass) { @@ -880,7 +933,23 @@ dzn_nir_polygon_point_mode_gs(const nir_shader *previous_shader, unsigned cull_m for (unsigned i = 0; i < num_vars; ++i) { nir_ssa_def *index = loop_index; nir_deref_instr *in_value = nir_build_deref_array(b, nir_build_deref_var(b, in[i]), index); - copy_vars(b, nir_build_deref_var(b, out[i]), in_value); + if (in[i] == pos_var && info->depth_bias) { + nir_ssa_def *bias_val; + if (info->depth_bias_dynamic) { + bias_val = load_dynamic_depth_bias(b, info); + } else { + assert(info->slope_scaled_depth_bias == 0.0f); + bias_val = nir_imm_float(b, info->constant_depth_bias); + } + bias_val = nir_fmul(b, bias_val, depth_bias_scale); + nir_ssa_def *old_val = nir_load_deref(b, in_value); + nir_ssa_def *new_val = nir_vector_insert_imm(b, old_val, + nir_fadd(b, nir_channel(b, old_val, 2), bias_val), + 2); + nir_store_var(b, out[i], new_val, 0xf); + } else { + copy_vars(b, nir_build_deref_var(b, out[i]), in_value); + } } nir_store_var(b, front_facing_var, front_facing, 0x1); nir_emit_vertex(b, 0); diff --git a/src/microsoft/vulkan/dzn_nir.h b/src/microsoft/vulkan/dzn_nir.h index 881d8e1ac17..176e0194265 100644 --- a/src/microsoft/vulkan/dzn_nir.h +++ b/src/microsoft/vulkan/dzn_nir.h @@ -158,7 +158,23 @@ dzn_nir_blit_vs(void); nir_shader * dzn_nir_blit_fs(const struct dzn_nir_blit_info *info); +struct dzn_nir_point_gs_info { + unsigned cull_mode; + bool front_ccw; + bool depth_bias; + bool depth_bias_dynamic; + DXGI_FORMAT ds_fmt; + /* Constant values */ + float constant_depth_bias; + float slope_scaled_depth_bias; + float depth_bias_clamp; + /* Used for loading dynamic values */ + struct { + uint32_t register_space; + uint32_t base_shader_register; + } runtime_data_cbv; +}; nir_shader * -dzn_nir_polygon_point_mode_gs(const nir_shader *vs, unsigned cull_mode, bool front_ccw); +dzn_nir_polygon_point_mode_gs(const nir_shader *vs, struct dzn_nir_point_gs_info *info); #endif diff --git a/src/microsoft/vulkan/dzn_pipeline.c b/src/microsoft/vulkan/dzn_pipeline.c index 8181de24618..f0ac0b6838d 100644 --- a/src/microsoft/vulkan/dzn_pipeline.c +++ b/src/microsoft/vulkan/dzn_pipeline.c @@ -776,11 +776,11 @@ dzn_graphics_pipeline_compile_shaders(struct dzn_device *device, active_stage_mask |= BITFIELD_BIT(stage); } - bool use_gs_for_polygon_mode_point = + pipeline->use_gs_for_polygon_mode_point = info->pRasterizationState && info->pRasterizationState->polygonMode == VK_POLYGON_MODE_POINT && !(active_stage_mask & (1 << MESA_SHADER_GEOMETRY)); - if (use_gs_for_polygon_mode_point) + if (pipeline->use_gs_for_polygon_mode_point) last_raster_stage = MESA_SHADER_GEOMETRY; enum dxil_spirv_yz_flip_mode yz_flip_mode = DXIL_SPIRV_YZ_FLIP_NONE; @@ -825,7 +825,7 @@ dzn_graphics_pipeline_compile_shaders(struct dzn_device *device, _mesa_sha1_update(&pipeline_hash_ctx, &z_flip_mask, sizeof(z_flip_mask)); _mesa_sha1_update(&pipeline_hash_ctx, &force_sample_rate_shading, sizeof(force_sample_rate_shading)); _mesa_sha1_update(&pipeline_hash_ctx, &lower_view_index, sizeof(lower_view_index)); - _mesa_sha1_update(&pipeline_hash_ctx, &use_gs_for_polygon_mode_point, sizeof(use_gs_for_polygon_mode_point)); + _mesa_sha1_update(&pipeline_hash_ctx, &pipeline->use_gs_for_polygon_mode_point, sizeof(pipeline->use_gs_for_polygon_mode_point)); u_foreach_bit(stage, active_stage_mask) { vk_pipeline_hash_shader_stage(stages[stage].info, NULL, stages[stage].spirv_hash); @@ -895,12 +895,25 @@ dzn_graphics_pipeline_compile_shaders(struct dzn_device *device, return ret; } - if (use_gs_for_polygon_mode_point) { + if (pipeline->use_gs_for_polygon_mode_point) { /* TODO: Cache; handle TES */ + struct dzn_nir_point_gs_info gs_info = { + .cull_mode = info->pRasterizationState->cullMode, + .front_ccw = info->pRasterizationState->frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE, + .depth_bias = info->pRasterizationState->depthBiasEnable, + .depth_bias_dynamic = pipeline->zsa.dynamic_depth_bias, + .ds_fmt = pipeline->zsa.ds_fmt, + .constant_depth_bias = info->pRasterizationState->depthBiasConstantFactor, + .slope_scaled_depth_bias = info->pRasterizationState->depthBiasSlopeFactor, + .depth_bias_clamp = info->pRasterizationState->depthBiasClamp, + .runtime_data_cbv = { + .register_space = DZN_REGISTER_SPACE_SYSVALS, + .base_shader_register = 0, + } + }; pipeline->templates.shaders[MESA_SHADER_GEOMETRY].nir = dzn_nir_polygon_point_mode_gs(pipeline->templates.shaders[MESA_SHADER_VERTEX].nir, - info->pRasterizationState->cullMode, - info->pRasterizationState->frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE); + &gs_info); struct dxil_spirv_runtime_conf conf = { .runtime_data_cbv = { @@ -976,7 +989,7 @@ dzn_graphics_pipeline_compile_shaders(struct dzn_device *device, if (stage == MESA_SHADER_FRAGMENT) { _mesa_sha1_update(&dxil_hash_ctx, &force_sample_rate_shading, sizeof(force_sample_rate_shading)); - _mesa_sha1_update(&dxil_hash_ctx, &use_gs_for_polygon_mode_point, sizeof(use_gs_for_polygon_mode_point)); + _mesa_sha1_update(&dxil_hash_ctx, &pipeline->use_gs_for_polygon_mode_point, sizeof(pipeline->use_gs_for_polygon_mode_point)); } _mesa_sha1_update(&dxil_hash_ctx, stages[stage].spirv_hash, sizeof(stages[stage].spirv_hash)); @@ -1881,10 +1894,10 @@ dzn_graphics_pipeline_create(struct dzn_device *device, pipeline->zsa.depth_bounds.dynamic = true; break; case VK_DYNAMIC_STATE_DEPTH_BIAS: + pipeline->zsa.dynamic_depth_bias = true; if (pdev->options16.DynamicDepthBiasSupported) { *flags |= D3D12_PIPELINE_STATE_FLAG_DYNAMIC_DEPTH_BIAS; } else { - pipeline->zsa.dynamic_depth_bias = true; ret = dzn_graphics_pipeline_prepare_for_variants(device, pipeline); if (ret) goto out; @@ -1961,6 +1974,7 @@ dzn_graphics_pipeline_create(struct dzn_device *device, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); + pipeline->zsa.ds_fmt = *ds_fmt; } pipeline->multiview.view_mask = MAX2(view_mask, 1); @@ -2144,7 +2158,8 @@ dzn_graphics_pipeline_get_state(struct dzn_graphics_pipeline *pipeline, if (dzn_graphics_pipeline_get_desc_template(pipeline, ib_strip_cut)) masked_key.ib_strip_cut = key->ib_strip_cut; - if (dzn_graphics_pipeline_get_desc_template(pipeline, rast) && + if (!pdev->options16.DynamicDepthBiasSupported && + dzn_graphics_pipeline_get_desc_template(pipeline, rast) && pipeline->zsa.dynamic_depth_bias) masked_key.depth_bias = key->depth_bias; @@ -2174,8 +2189,7 @@ dzn_graphics_pipeline_get_state(struct dzn_graphics_pipeline *pipeline, D3D12_RASTERIZER_DESC *rast = dzn_graphics_pipeline_get_desc(pipeline, stream_buf, rast); - if (rast && pipeline->zsa.dynamic_depth_bias) { - assert(!pdev->options16.DynamicDepthBiasSupported); + if (!pdev->options16.DynamicDepthBiasSupported && rast && pipeline->zsa.dynamic_depth_bias) { rast->DepthBias = translate_depth_bias(masked_key.depth_bias.constant_factor); rast->DepthBiasClamp = masked_key.depth_bias.clamp; rast->SlopeScaledDepthBias = masked_key.depth_bias.slope_factor; diff --git a/src/microsoft/vulkan/dzn_private.h b/src/microsoft/vulkan/dzn_private.h index 946bf2735ac..011ce1f07eb 100644 --- a/src/microsoft/vulkan/dzn_private.h +++ b/src/microsoft/vulkan/dzn_private.h @@ -969,6 +969,7 @@ struct dzn_graphics_pipeline { float min, max; } depth_bounds; bool dynamic_depth_bias; + DXGI_FORMAT ds_fmt; } zsa; struct { @@ -977,6 +978,7 @@ struct dzn_graphics_pipeline { } blend; bool rast_disabled_from_missing_position; + bool use_gs_for_polygon_mode_point; struct { uint32_t view_mask;