dzn: Handle depth bias for point fill mode emulation

Fixes dEQP-VK.draw.renderpass.depth_bias.depth_bias_triangle_list_point

This is not complete, there's no slope scale or clamp handling, but it
does handle static or dynamic (though dynamic is untested).

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22639>
This commit is contained in:
Jesse Natalie 2023-04-21 11:13:12 -07:00 committed by Marge Bot
parent 542febcf59
commit a12a15a9ea
6 changed files with 129 additions and 20 deletions

View file

@ -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 {

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -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;