[Vulkan] Add gamma_render_target_as_srgb support
This commit is contained in:
@@ -368,12 +368,14 @@ class SpirvShaderTranslator : public ShaderTranslator {
|
||||
bool native_2x_msaa_with_attachments,
|
||||
bool native_2x_msaa_no_attachments,
|
||||
bool edram_fragment_shader_interlock,
|
||||
bool gamma_render_target_as_srgb = false,
|
||||
uint32_t draw_resolution_scale_x = 1,
|
||||
uint32_t draw_resolution_scale_y = 1)
|
||||
: features_(features),
|
||||
native_2x_msaa_with_attachments_(native_2x_msaa_with_attachments),
|
||||
native_2x_msaa_no_attachments_(native_2x_msaa_no_attachments),
|
||||
edram_fragment_shader_interlock_(edram_fragment_shader_interlock),
|
||||
gamma_render_target_as_srgb_(gamma_render_target_as_srgb),
|
||||
draw_resolution_scale_x_(draw_resolution_scale_x),
|
||||
draw_resolution_scale_y_(draw_resolution_scale_y) {}
|
||||
|
||||
@@ -754,6 +756,9 @@ class SpirvShaderTranslator : public ShaderTranslator {
|
||||
// flow of the main function, and that there are no returns before either
|
||||
// (there's a single return from the shader).
|
||||
bool edram_fragment_shader_interlock_;
|
||||
// Whether with host render targets, k_8_8_8_8_GAMMA render targets are
|
||||
// represented as host sRGB (gamma applied by the host after blending).
|
||||
bool gamma_render_target_as_srgb_;
|
||||
|
||||
// Is currently writing the empty depth-only pixel shader, such as for depth
|
||||
// and stencil testing with fragment shader interlock.
|
||||
|
||||
@@ -1251,41 +1251,45 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() {
|
||||
if_rt_write_mask_not_empty.makeEndIf();
|
||||
if_fsi_color_written.makeEndIf();
|
||||
} else {
|
||||
// Convert to gamma space - this is incorrect, since it must be done
|
||||
// after blending on the Xbox 360, but this is just one of many blending
|
||||
// issues in the host render target path.
|
||||
// TODO(Triang3l): Gamma as sRGB check.
|
||||
uint_vector_temp_.clear();
|
||||
uint_vector_temp_.push_back(0);
|
||||
uint_vector_temp_.push_back(1);
|
||||
uint_vector_temp_.push_back(2);
|
||||
spv::Id color_rgb = builder_->createRvalueSwizzle(
|
||||
spv::NoPrecision, type_float3_, color, uint_vector_temp_);
|
||||
spv::Id is_gamma = builder_->createBinOp(
|
||||
spv::OpINotEqual, type_bool_,
|
||||
builder_->createBinOp(
|
||||
spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_,
|
||||
builder_->makeUintConstant(kSysFlag_ConvertColor0ToGamma
|
||||
<< color_target_index)),
|
||||
const_uint_0_);
|
||||
SpirvBuilder::IfBuilder if_gamma(
|
||||
is_gamma, spv::SelectionControlDontFlattenMask, *builder_);
|
||||
spv::Id color_rgb_gamma = LinearToPWLGamma(color_rgb, false);
|
||||
if_gamma.makeEndIf();
|
||||
color_rgb = if_gamma.createMergePhi(color_rgb_gamma, color_rgb);
|
||||
{
|
||||
std::unique_ptr<spv::Instruction> color_rgba_shuffle_op =
|
||||
std::make_unique<spv::Instruction>(
|
||||
builder_->getUniqueId(), type_float4_, spv::OpVectorShuffle);
|
||||
color_rgba_shuffle_op->addIdOperand(color_rgb);
|
||||
color_rgba_shuffle_op->addIdOperand(color);
|
||||
color_rgba_shuffle_op->addImmediateOperand(0);
|
||||
color_rgba_shuffle_op->addImmediateOperand(1);
|
||||
color_rgba_shuffle_op->addImmediateOperand(2);
|
||||
color_rgba_shuffle_op->addImmediateOperand(3 + 3);
|
||||
color = color_rgba_shuffle_op->getResultId();
|
||||
builder_->getBuildPoint()->addInstruction(
|
||||
std::move(color_rgba_shuffle_op));
|
||||
if (!gamma_render_target_as_srgb_) {
|
||||
// Convert to gamma space - this is incorrect, since it must be done
|
||||
// after blending on the Xbox 360, but this is just one of many
|
||||
// blending issues in the host render target path. When
|
||||
// gamma_render_target_as_srgb_ is enabled, the host handles gamma
|
||||
// conversion via sRGB render target format after blending.
|
||||
uint_vector_temp_.clear();
|
||||
uint_vector_temp_.push_back(0);
|
||||
uint_vector_temp_.push_back(1);
|
||||
uint_vector_temp_.push_back(2);
|
||||
spv::Id color_rgb = builder_->createRvalueSwizzle(
|
||||
spv::NoPrecision, type_float3_, color, uint_vector_temp_);
|
||||
spv::Id is_gamma = builder_->createBinOp(
|
||||
spv::OpINotEqual, type_bool_,
|
||||
builder_->createBinOp(
|
||||
spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_,
|
||||
builder_->makeUintConstant(kSysFlag_ConvertColor0ToGamma
|
||||
<< color_target_index)),
|
||||
const_uint_0_);
|
||||
SpirvBuilder::IfBuilder if_gamma(
|
||||
is_gamma, spv::SelectionControlDontFlattenMask, *builder_);
|
||||
spv::Id color_rgb_gamma = LinearToPWLGamma(color_rgb, false);
|
||||
if_gamma.makeEndIf();
|
||||
color_rgb = if_gamma.createMergePhi(color_rgb_gamma, color_rgb);
|
||||
{
|
||||
std::unique_ptr<spv::Instruction> color_rgba_shuffle_op =
|
||||
std::make_unique<spv::Instruction>(builder_->getUniqueId(),
|
||||
type_float4_,
|
||||
spv::OpVectorShuffle);
|
||||
color_rgba_shuffle_op->addIdOperand(color_rgb);
|
||||
color_rgba_shuffle_op->addIdOperand(color);
|
||||
color_rgba_shuffle_op->addImmediateOperand(0);
|
||||
color_rgba_shuffle_op->addImmediateOperand(1);
|
||||
color_rgba_shuffle_op->addImmediateOperand(2);
|
||||
color_rgba_shuffle_op->addImmediateOperand(3 + 3);
|
||||
color = color_rgba_shuffle_op->getResultId();
|
||||
builder_->getBuildPoint()->addInstruction(
|
||||
std::move(color_rgba_shuffle_op));
|
||||
}
|
||||
}
|
||||
|
||||
builder_->createStore(color, color_variable);
|
||||
|
||||
@@ -59,6 +59,7 @@ bool VulkanPipelineCache::Initialize() {
|
||||
render_target_cache_.msaa_2x_attachments_supported(),
|
||||
render_target_cache_.msaa_2x_no_attachments_supported(),
|
||||
edram_fragment_shader_interlock,
|
||||
render_target_cache_.gamma_render_target_as_srgb(),
|
||||
render_target_cache_.draw_resolution_scale_x(),
|
||||
render_target_cache_.draw_resolution_scale_y());
|
||||
|
||||
|
||||
@@ -520,6 +520,7 @@ bool VulkanRenderTargetCache::Initialize(uint32_t shared_memory_binding_count) {
|
||||
// Host render targets.
|
||||
|
||||
depth_float24_round_ = cvars::depth_float24_round;
|
||||
gamma_render_target_as_srgb_ = cvars::gamma_render_target_as_srgb;
|
||||
|
||||
// Host depth storing pipeline layout.
|
||||
VkDescriptorSetLayout host_depth_store_descriptor_set_layouts[] = {
|
||||
|
||||
@@ -155,6 +155,9 @@ class VulkanRenderTargetCache final : public RenderTargetCache {
|
||||
return depth_unorm24_vulkan_format_supported_;
|
||||
}
|
||||
bool depth_float24_round() const { return depth_float24_round_; }
|
||||
bool gamma_render_target_as_srgb() const {
|
||||
return gamma_render_target_as_srgb_;
|
||||
}
|
||||
|
||||
bool msaa_2x_attachments_supported() const {
|
||||
return msaa_2x_attachments_supported_;
|
||||
|
||||
Reference in New Issue
Block a user