mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 22:06:59 +01:00
shader: dual-source blending (Vulkan)
This commit is contained in:
@@ -593,6 +593,21 @@ PipelineCache::GraphicsPrograms PipelineCache::GetGraphicsPrograms(
|
|||||||
ShaderParams pixel_params;
|
ShaderParams pixel_params;
|
||||||
if (pixel_active) {
|
if (pixel_active) {
|
||||||
pixel_params = PrepareProgram(pixel_regs, sh, target_export_mapping, pixel_info);
|
pixel_params = PrepareProgram(pixel_regs, sh, target_export_mapping, pixel_info);
|
||||||
|
const auto& blend = context.GetBlendControl(0);
|
||||||
|
const auto is_dual_source = [](uint8_t factor) {
|
||||||
|
return factor >= static_cast<uint8_t>(Prospero::BlendFactor::kSrc1Color) &&
|
||||||
|
factor <= static_cast<uint8_t>(Prospero::BlendFactor::kOneMinusSrc1Alpha);
|
||||||
|
};
|
||||||
|
pixel_info.dual_source_blending =
|
||||||
|
blend.enable && !context.GetRenderTarget(0).info.blend_bypass &&
|
||||||
|
(is_dual_source(blend.color_srcblend) || is_dual_source(blend.color_destblend) ||
|
||||||
|
(blend.separate_alpha_blend &&
|
||||||
|
(is_dual_source(blend.alpha_srcblend) || is_dual_source(blend.alpha_destblend))));
|
||||||
|
if (pixel_info.dual_source_blending) {
|
||||||
|
// MRT1 supplies a second blend source for the same render target as MRT0.
|
||||||
|
pixel_info.target_output_mode[1] = pixel_info.target_output_mode[0];
|
||||||
|
pixel_info.target_export_mapping[1] = pixel_info.target_export_mapping[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (context.GetClipControl().clip_disable) {
|
if (context.GetClipControl().clip_disable) {
|
||||||
const auto& viewport = context.GetScreenViewport().viewports[0];
|
const auto& viewport = context.GetScreenViewport().viewports[0];
|
||||||
|
|||||||
@@ -610,10 +610,11 @@ static vk::Device VulkanCreateDevice(GraphicContext& graphics,
|
|||||||
graphics.mesh_shader_properties.maxMeshOutputPrimitives,
|
graphics.mesh_shader_properties.maxMeshOutputPrimitives,
|
||||||
graphics.mesh_shader_properties.maxMeshSharedMemorySize);
|
graphics.mesh_shader_properties.maxMeshSharedMemorySize);
|
||||||
}
|
}
|
||||||
// VulkanFindPhysicalDevice already checked the required creation features. These two
|
// VulkanFindPhysicalDevice already checked the required creation features. These
|
||||||
// requirements are specific to this creation path and are not part of device selection.
|
// requirements are specific to this creation path and are not part of device selection.
|
||||||
EXIT_NOT_IMPLEMENTED(supported_features2.features.shaderInt64 != VK_TRUE);
|
EXIT_NOT_IMPLEMENTED(supported_features2.features.shaderInt64 != VK_TRUE);
|
||||||
EXIT_NOT_IMPLEMENTED(supported_features2.features.vertexPipelineStoresAndAtomics != VK_TRUE);
|
EXIT_NOT_IMPLEMENTED(supported_features2.features.vertexPipelineStoresAndAtomics != VK_TRUE);
|
||||||
|
EXIT_NOT_IMPLEMENTED(supported_features2.features.dualSrcBlend != VK_TRUE);
|
||||||
vk::PhysicalDeviceFeatures device_features {};
|
vk::PhysicalDeviceFeatures device_features {};
|
||||||
device_features.fragmentStoresAndAtomics = VK_TRUE;
|
device_features.fragmentStoresAndAtomics = VK_TRUE;
|
||||||
device_features.samplerAnisotropy = VK_TRUE;
|
device_features.samplerAnisotropy = VK_TRUE;
|
||||||
@@ -624,6 +625,7 @@ static vk::Device VulkanCreateDevice(GraphicContext& graphics,
|
|||||||
device_features.shaderStorageImageWriteWithoutFormat = VK_TRUE;
|
device_features.shaderStorageImageWriteWithoutFormat = VK_TRUE;
|
||||||
device_features.shaderImageGatherExtended = VK_TRUE;
|
device_features.shaderImageGatherExtended = VK_TRUE;
|
||||||
device_features.independentBlend = VK_TRUE;
|
device_features.independentBlend = VK_TRUE;
|
||||||
|
device_features.dualSrcBlend = VK_TRUE;
|
||||||
device_features.tessellationShader = VK_TRUE;
|
device_features.tessellationShader = VK_TRUE;
|
||||||
device_features.sampleRateShading = VK_TRUE;
|
device_features.sampleRateShading = VK_TRUE;
|
||||||
device_features.depthBiasClamp = VK_TRUE;
|
device_features.depthBiasClamp = VK_TRUE;
|
||||||
|
|||||||
@@ -553,8 +553,17 @@ void DefineOutputs(EmitterState& state) {
|
|||||||
const auto type = uint_output ? TypeU32Vector(state, 4) : TypeF32Vector(state, 4);
|
const auto type = uint_output ? TypeU32Vector(state, 4) : TypeF32Vector(state, 4);
|
||||||
binding.variable_id = DefineInterfaceVariable(state, type, spv::StorageClassOutput,
|
binding.variable_id = DefineInterfaceVariable(state, type, spv::StorageClassOutput,
|
||||||
binding.debug_name.c_str());
|
binding.debug_name.c_str());
|
||||||
|
const bool dual_source = binding.kind == IR::StageOutputKind::Mrt &&
|
||||||
|
state.program.stage == ShaderType::Pixel &&
|
||||||
|
state.input_info.pixel->dual_source_blending;
|
||||||
|
EXIT_NOT_IMPLEMENTED(dual_source && binding.index > 1);
|
||||||
state.builder.AddAnnotation(spv::OpDecorate, binding.variable_id,
|
state.builder.AddAnnotation(spv::OpDecorate, binding.variable_id,
|
||||||
spv::DecorationLocation, binding.location);
|
spv::DecorationLocation,
|
||||||
|
dual_source ? 0u : binding.location);
|
||||||
|
if (dual_source) {
|
||||||
|
state.builder.AddAnnotation(spv::OpDecorate, binding.variable_id,
|
||||||
|
spv::DecorationIndex, binding.index);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -721,6 +721,7 @@ void BuildStageStaticKey(const ShaderPixelInputInfo& info, std::vector<uint32_t>
|
|||||||
key.push_back(static_cast<uint32_t>(info.ps_depth_export_enable));
|
key.push_back(static_cast<uint32_t>(info.ps_depth_export_enable));
|
||||||
key.push_back(static_cast<uint32_t>(info.ps_sample_mask_export_enable));
|
key.push_back(static_cast<uint32_t>(info.ps_sample_mask_export_enable));
|
||||||
key.push_back(static_cast<uint32_t>(info.ps_early_z));
|
key.push_back(static_cast<uint32_t>(info.ps_early_z));
|
||||||
|
key.push_back(static_cast<uint32_t>(info.dual_source_blending));
|
||||||
key.insert(key.end(), std::begin(info.target_output_mode), std::end(info.target_output_mode));
|
key.insert(key.end(), std::begin(info.target_output_mode), std::end(info.target_output_mode));
|
||||||
for (uint32_t base = 0; base < info.target_export_mapping.size(); base += 4u) {
|
for (uint32_t base = 0; base < info.target_export_mapping.size(); base += 4u) {
|
||||||
uint32_t packed = 0;
|
uint32_t packed = 0;
|
||||||
|
|||||||
@@ -175,6 +175,7 @@ struct ShaderPixelInputInfo {
|
|||||||
bool ps_depth_export_enable = false;
|
bool ps_depth_export_enable = false;
|
||||||
bool ps_sample_mask_export_enable = false;
|
bool ps_sample_mask_export_enable = false;
|
||||||
bool ps_sample_shading = false;
|
bool ps_sample_shading = false;
|
||||||
|
bool dual_source_blending = false;
|
||||||
bool ps_early_z = false;
|
bool ps_early_z = false;
|
||||||
bool ps_execute_on_noop = false;
|
bool ps_execute_on_noop = false;
|
||||||
ShaderStageRuntime stage;
|
ShaderStageRuntime stage;
|
||||||
|
|||||||
Reference in New Issue
Block a user