Vulkan: add two sided stencil/logic op/depth bounds test support (#1767)

* Vulkan: add two sided stencil support

* Vulkan: add logic op support

* Vulkan: add depth bound test support

* Drop off wrong case

* Minor fixes
This commit is contained in:
raven02 2016-06-13 19:10:59 +08:00 committed by Ivan
parent 3956b21cb7
commit caf5894152
4 changed files with 83 additions and 9 deletions

View File

@ -128,8 +128,6 @@ D3D12_COMPARISON_FUNC get_compare_func(u32 op)
case CELL_GCM_NOTEQUAL: return D3D12_COMPARISON_FUNC_NOT_EQUAL;
case CELL_GCM_GEQUAL: return D3D12_COMPARISON_FUNC_GREATER_EQUAL;
case CELL_GCM_ALWAYS: return D3D12_COMPARISON_FUNC_ALWAYS;
case CELL_GCM_ZERO:
break;
}
throw EXCEPTION("Invalid or unsupported compare func (0x%x)", op);
}

View File

@ -12,6 +12,8 @@ namespace vk
gpu_formats_support get_optimal_tiling_supported_formats(VkPhysicalDevice physical_device);
VkFormat get_compatible_depth_surface_format(const gpu_formats_support &support, rsx::surface_depth_format format);
VkStencilOp get_stencil_op(u32 op);
VkLogicOp get_logic_op(u32 op);
std::tuple<VkFilter, VkSamplerMipmapMode> get_min_filter_and_mip(rsx::texture_minify_filter min_filter);
VkFilter get_mag_filter(rsx::texture_magnify_filter mag_filter);

View File

@ -181,6 +181,30 @@ namespace vk
}
}
VkLogicOp get_logic_op(u32 op)
{
switch (op)
{
case CELL_GCM_CLEAR: return VK_LOGIC_OP_CLEAR;
case CELL_GCM_AND: return VK_LOGIC_OP_AND;
case CELL_GCM_AND_REVERSE: return VK_LOGIC_OP_AND_REVERSE;
case CELL_GCM_COPY: return VK_LOGIC_OP_COPY;
case CELL_GCM_AND_INVERTED: return VK_LOGIC_OP_AND_INVERTED;
case CELL_GCM_NOOP: return VK_LOGIC_OP_NO_OP;
case CELL_GCM_XOR: return VK_LOGIC_OP_XOR;
case CELL_GCM_OR: return VK_LOGIC_OP_OR;
case CELL_GCM_NOR: return VK_LOGIC_OP_NOR;
case CELL_GCM_EQUIV: return VK_LOGIC_OP_EQUIVALENT;
case CELL_GCM_INVERT: return VK_LOGIC_OP_INVERT;
case CELL_GCM_OR_REVERSE: return VK_LOGIC_OP_OR_REVERSE;
case CELL_GCM_COPY_INVERTED: return VK_LOGIC_OP_COPY_INVERTED;
case CELL_GCM_OR_INVERTED: return VK_LOGIC_OP_OR_INVERTED;
case CELL_GCM_NAND: return VK_LOGIC_OP_NAND;
default:
throw EXCEPTION("Unknown logic op 0x%X", op);
}
}
VkBlendFactor get_blend_factor(u16 factor)
{
switch (factor)
@ -217,6 +241,23 @@ namespace vk
throw EXCEPTION("Unknown blend op: 0x%X", op);
}
}
VkStencilOp get_stencil_op(u32 op)
{
switch (op)
{
case CELL_GCM_KEEP: return VK_STENCIL_OP_KEEP;
case CELL_GCM_ZERO: return VK_STENCIL_OP_ZERO;
case CELL_GCM_REPLACE: return VK_STENCIL_OP_REPLACE;
case CELL_GCM_INCR: return VK_STENCIL_OP_INCREMENT_AND_CLAMP;
case CELL_GCM_DECR: return VK_STENCIL_OP_DECREMENT_AND_CLAMP;
case CELL_GCM_INVERT: return VK_STENCIL_OP_INVERT;
case CELL_GCM_INCR_WRAP: return VK_STENCIL_OP_INCREMENT_AND_WRAP;
case CELL_GCM_DECR_WRAP: return VK_STENCIL_OP_DECREMENT_AND_WRAP;
default:
throw EXCEPTION("Unknown stencil op: 0x%X", op);
}
}
}
@ -886,17 +927,48 @@ bool VKGSRender::load_program()
}
}
if (rsx::method_registers[NV4097_SET_LOGIC_OP_ENABLE])
{
properties.cs.logicOpEnable = true;
properties.cs.logicOp = vk::get_logic_op(rsx::method_registers[NV4097_SET_LOGIC_OP]);
}
properties.ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
properties.ds.depthWriteEnable = (!!rsx::method_registers[NV4097_SET_DEPTH_MASK]) ? VK_TRUE : VK_FALSE;
properties.ds.depthBoundsTestEnable = VK_FALSE;
properties.ds.back.failOp = VK_STENCIL_OP_KEEP;
properties.ds.back.passOp = VK_STENCIL_OP_KEEP;
properties.ds.back.compareOp = VK_COMPARE_OP_ALWAYS;
properties.ds.stencilTestEnable = VK_FALSE;
properties.ds.front = properties.ds.back;
if (rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE])
{
properties.ds.depthBoundsTestEnable = VK_TRUE;
properties.ds.minDepthBounds = (f32&)rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_MIN];
properties.ds.maxDepthBounds = (f32&)rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_MAX];
}
else
properties.ds.depthBoundsTestEnable = VK_FALSE;
if (rsx::method_registers[NV4097_SET_STENCIL_TEST_ENABLE])
{
properties.ds.stencilTestEnable = VK_TRUE;
properties.ds.front.writeMask = rsx::method_registers[NV4097_SET_STENCIL_MASK];
properties.ds.front.compareMask = rsx::method_registers[NV4097_SET_STENCIL_FUNC_MASK];
properties.ds.front.reference = rsx::method_registers[NV4097_SET_STENCIL_FUNC_REF];
properties.ds.front.failOp = vk::get_stencil_op(rsx::method_registers[NV4097_SET_STENCIL_OP_FAIL]);
properties.ds.front.passOp = vk::get_stencil_op(rsx::method_registers[NV4097_SET_STENCIL_OP_ZPASS]);
properties.ds.front.depthFailOp = vk::get_stencil_op(rsx::method_registers[NV4097_SET_STENCIL_OP_ZFAIL]);
properties.ds.front.compareOp = vk::compare_op(rsx::method_registers[NV4097_SET_STENCIL_FUNC]);
if (rsx::method_registers[NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE])
{
properties.ds.back.failOp = vk::get_stencil_op(rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_FAIL]);
properties.ds.back.passOp = vk::get_stencil_op(rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_ZPASS]);
properties.ds.back.depthFailOp = vk::get_stencil_op(rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_ZFAIL]);
properties.ds.back.compareOp = vk::compare_op(rsx::method_registers[NV4097_SET_BACK_STENCIL_FUNC]);
}
else
properties.ds.back = properties.ds.front;
}
else
properties.ds.stencilTestEnable = VK_FALSE;
if (!!rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE])
{
properties.ds.depthTestEnable = VK_TRUE;

View File

@ -11,6 +11,8 @@ namespace vk
VkPipelineInputAssemblyStateCreateInfo ia;
VkPipelineDepthStencilStateCreateInfo ds;
VkPipelineColorBlendAttachmentState att_state[4];
VkPipelineColorBlendStateCreateInfo cs;
VkRenderPass render_pass;
int num_targets;