mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 19:07:01 +02:00
shader: dual-source blending (Vulkan)
This commit is contained in:
@@ -593,6 +593,21 @@ PipelineCache::GraphicsPrograms PipelineCache::GetGraphicsPrograms(
|
||||
ShaderParams pixel_params;
|
||||
if (pixel_active) {
|
||||
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) {
|
||||
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.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.
|
||||
EXIT_NOT_IMPLEMENTED(supported_features2.features.shaderInt64 != VK_TRUE);
|
||||
EXIT_NOT_IMPLEMENTED(supported_features2.features.vertexPipelineStoresAndAtomics != VK_TRUE);
|
||||
EXIT_NOT_IMPLEMENTED(supported_features2.features.dualSrcBlend != VK_TRUE);
|
||||
vk::PhysicalDeviceFeatures device_features {};
|
||||
device_features.fragmentStoresAndAtomics = VK_TRUE;
|
||||
device_features.samplerAnisotropy = VK_TRUE;
|
||||
@@ -624,6 +625,7 @@ static vk::Device VulkanCreateDevice(GraphicContext& graphics,
|
||||
device_features.shaderStorageImageWriteWithoutFormat = VK_TRUE;
|
||||
device_features.shaderImageGatherExtended = VK_TRUE;
|
||||
device_features.independentBlend = VK_TRUE;
|
||||
device_features.dualSrcBlend = VK_TRUE;
|
||||
device_features.tessellationShader = VK_TRUE;
|
||||
device_features.sampleRateShading = 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);
|
||||
binding.variable_id = DefineInterfaceVariable(state, type, spv::StorageClassOutput,
|
||||
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,
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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_sample_mask_export_enable));
|
||||
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));
|
||||
for (uint32_t base = 0; base < info.target_export_mapping.size(); base += 4u) {
|
||||
uint32_t packed = 0;
|
||||
|
||||
@@ -175,6 +175,7 @@ struct ShaderPixelInputInfo {
|
||||
bool ps_depth_export_enable = false;
|
||||
bool ps_sample_mask_export_enable = false;
|
||||
bool ps_sample_shading = false;
|
||||
bool dual_source_blending = false;
|
||||
bool ps_early_z = false;
|
||||
bool ps_execute_on_noop = false;
|
||||
ShaderStageRuntime stage;
|
||||
|
||||
Reference in New Issue
Block a user