mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-01-17 04:06:25 +00:00
vulkan: Emulate depth clip control when extension is not available. (#762)
Some checks are pending
Reuse / reuse (push) Waiting to run
Clang Format / clang-format (push) Waiting to run
Linux-Qt / build (push) Waiting to run
Linux / build (push) Waiting to run
macOS-Qt / build (push) Waiting to run
macOS / build (push) Waiting to run
Windows-Qt / build (push) Waiting to run
Windows / build (push) Waiting to run
Some checks are pending
Reuse / reuse (push) Waiting to run
Clang Format / clang-format (push) Waiting to run
Linux-Qt / build (push) Waiting to run
Linux / build (push) Waiting to run
macOS-Qt / build (push) Waiting to run
macOS / build (push) Waiting to run
Windows-Qt / build (push) Waiting to run
Windows / build (push) Waiting to run
This commit is contained in:
parent
e340583a7f
commit
b87e6f3838
|
@ -10,7 +10,21 @@ void EmitPrologue(EmitContext& ctx) {
|
|||
ctx.DefineBufferOffsets();
|
||||
}
|
||||
|
||||
void EmitEpilogue(EmitContext& ctx) {}
|
||||
void ConvertDepthMode(EmitContext& ctx) {
|
||||
const Id type{ctx.F32[1]};
|
||||
const Id position{ctx.OpLoad(ctx.F32[4], ctx.output_position)};
|
||||
const Id z{ctx.OpCompositeExtract(type, position, 2u)};
|
||||
const Id w{ctx.OpCompositeExtract(type, position, 3u)};
|
||||
const Id screen_depth{ctx.OpFMul(type, ctx.OpFAdd(type, z, w), ctx.Constant(type, 0.5f))};
|
||||
const Id vector{ctx.OpCompositeInsert(ctx.F32[4], screen_depth, position, 2u)};
|
||||
ctx.OpStore(ctx.output_position, vector);
|
||||
}
|
||||
|
||||
void EmitEpilogue(EmitContext& ctx) {
|
||||
if (ctx.stage == Stage::Vertex && ctx.runtime_info.vs_info.emulate_depth_negative_one_to_one) {
|
||||
ConvertDepthMode(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void EmitDiscard(EmitContext& ctx) {
|
||||
ctx.OpDemoteToHelperInvocationEXT();
|
||||
|
|
|
@ -63,9 +63,10 @@ using VsOutputMap = std::array<VsOutput, 4>;
|
|||
|
||||
struct VertexRuntimeInfo {
|
||||
boost::container::static_vector<VsOutputMap, 3> outputs;
|
||||
bool emulate_depth_negative_one_to_one{};
|
||||
|
||||
bool operator==(const VertexRuntimeInfo& other) const noexcept {
|
||||
return true;
|
||||
return emulate_depth_negative_one_to_one == other.emulate_depth_negative_one_to_one;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul
|
|||
};
|
||||
|
||||
const vk::PipelineViewportStateCreateInfo viewport_info = {
|
||||
.pNext = &clip_control,
|
||||
.pNext = instance.IsDepthClipControlSupported() ? &clip_control : nullptr,
|
||||
.viewportCount = 1,
|
||||
.pViewports = &viewport,
|
||||
.scissorCount = 1,
|
||||
|
|
|
@ -207,7 +207,7 @@ bool Instance::CreateDevice() {
|
|||
external_memory_host = add_extension(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME);
|
||||
custom_border_color = add_extension(VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME);
|
||||
add_extension(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
|
||||
const bool depth_clip_control = add_extension(VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME);
|
||||
depth_clip_control = add_extension(VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME);
|
||||
add_extension(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME);
|
||||
workgroup_memory_explicit_layout =
|
||||
add_extension(VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME);
|
||||
|
|
|
@ -117,6 +117,11 @@ public:
|
|||
return external_memory_host;
|
||||
}
|
||||
|
||||
/// Returns true when VK_EXT_depth_clip_control is supported
|
||||
bool IsDepthClipControlSupported() const {
|
||||
return depth_clip_control;
|
||||
}
|
||||
|
||||
/// Returns true when VK_EXT_color_write_enable is supported
|
||||
bool IsColorWriteEnableSupported() const {
|
||||
return color_write_en;
|
||||
|
@ -257,6 +262,7 @@ private:
|
|||
bool fragment_shader_barycentric{};
|
||||
bool shader_stencil_export{};
|
||||
bool external_memory_host{};
|
||||
bool depth_clip_control{};
|
||||
bool workgroup_memory_explicit_layout{};
|
||||
bool color_write_en{};
|
||||
bool vertex_input_dynamic_state{};
|
||||
|
|
|
@ -69,28 +69,32 @@ void GatherVertexOutputs(Shader::VertexRuntimeInfo& info,
|
|||
: (ctl.IsCullDistEnabled(7) ? VsOutput::CullDist7 : VsOutput::None));
|
||||
}
|
||||
|
||||
Shader::RuntimeInfo BuildRuntimeInfo(Shader::Stage stage, const GraphicsPipelineKey& key,
|
||||
const AmdGpu::Liverpool::Regs& regs) {
|
||||
Shader::RuntimeInfo PipelineCache::BuildRuntimeInfo(Shader::Stage stage) {
|
||||
auto info = Shader::RuntimeInfo{stage};
|
||||
const auto& regs = liverpool->regs;
|
||||
switch (stage) {
|
||||
case Shader::Stage::Vertex: {
|
||||
info.num_user_data = regs.vs_program.settings.num_user_regs;
|
||||
info.num_input_vgprs = regs.vs_program.settings.vgpr_comp_cnt;
|
||||
GatherVertexOutputs(info.vs_info, regs.vs_output_control);
|
||||
info.vs_info.emulate_depth_negative_one_to_one =
|
||||
!instance.IsDepthClipControlSupported() &&
|
||||
regs.clipper_control.clip_space == Liverpool::ClipSpace::MinusWToW;
|
||||
break;
|
||||
}
|
||||
case Shader::Stage::Fragment: {
|
||||
info.num_user_data = regs.ps_program.settings.num_user_regs;
|
||||
std::ranges::transform(key.mrt_swizzles, info.fs_info.mrt_swizzles.begin(),
|
||||
std::ranges::transform(graphics_key.mrt_swizzles, info.fs_info.mrt_swizzles.begin(),
|
||||
[](Liverpool::ColorBuffer::SwapMode mode) {
|
||||
return static_cast<Shader::MrtSwizzle>(mode);
|
||||
});
|
||||
const auto& ps_inputs = regs.ps_inputs;
|
||||
for (u32 i = 0; i < regs.num_interp; i++) {
|
||||
info.fs_info.inputs.push_back({
|
||||
.param_index = u8(regs.ps_inputs[i].input_offset.Value()),
|
||||
.is_default = bool(regs.ps_inputs[i].use_default),
|
||||
.is_flat = bool(regs.ps_inputs[i].flat_shade),
|
||||
.default_value = u8(regs.ps_inputs[i].default_value),
|
||||
.param_index = u8(ps_inputs[i].input_offset.Value()),
|
||||
.is_default = bool(ps_inputs[i].use_default),
|
||||
.is_flat = bool(ps_inputs[i].flat_shade),
|
||||
.default_value = u8(ps_inputs[i].default_value),
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
@ -327,7 +331,7 @@ vk::ShaderModule PipelineCache::CompileModule(Shader::Info& info,
|
|||
|
||||
std::tuple<const Shader::Info*, vk::ShaderModule, u64> PipelineCache::GetProgram(
|
||||
Shader::Stage stage, Shader::ShaderParams params, u32& binding) {
|
||||
const auto runtime_info = BuildRuntimeInfo(stage, graphics_key, liverpool->regs);
|
||||
const auto runtime_info = BuildRuntimeInfo(stage);
|
||||
auto [it_pgm, new_program] = program_cache.try_emplace(params.hash);
|
||||
if (new_program) {
|
||||
Program* program = program_pool.Create(stage, params);
|
||||
|
|
|
@ -60,6 +60,7 @@ private:
|
|||
std::string_view ext);
|
||||
vk::ShaderModule CompileModule(Shader::Info& info, const Shader::RuntimeInfo& runtime_info,
|
||||
std::span<const u32> code, size_t perm_idx, u32& binding);
|
||||
Shader::RuntimeInfo BuildRuntimeInfo(Shader::Stage stage);
|
||||
|
||||
private:
|
||||
const Instance& instance;
|
||||
|
|
Loading…
Reference in a new issue