radv/meta: add srgb conversion to end of resolve shader.
If we are resolving into an srgb dest, we need to convert to linear so the store does the conversion back. This should fix some wierdness seen when we subresolves hit the compute path. Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
@@ -32,7 +32,7 @@
|
|||||||
#include "vk_format.h"
|
#include "vk_format.h"
|
||||||
|
|
||||||
static nir_shader *
|
static nir_shader *
|
||||||
build_resolve_compute_shader(struct radv_device *dev, bool is_integer, int samples)
|
build_resolve_compute_shader(struct radv_device *dev, bool is_integer, bool is_srgb, int samples)
|
||||||
{
|
{
|
||||||
nir_builder b;
|
nir_builder b;
|
||||||
char name[64];
|
char name[64];
|
||||||
@@ -45,7 +45,7 @@ build_resolve_compute_shader(struct radv_device *dev, bool is_integer, int sampl
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
GLSL_TYPE_FLOAT);
|
GLSL_TYPE_FLOAT);
|
||||||
snprintf(name, 64, "meta_resolve_cs-%d-%s", samples, is_integer ? "int" : "float");
|
snprintf(name, 64, "meta_resolve_cs-%d-%s", samples, is_integer ? "int" : (is_srgb ? "srgb" : "float"));
|
||||||
nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_COMPUTE, NULL);
|
nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_COMPUTE, NULL);
|
||||||
b.shader->info->name = ralloc_strdup(b.shader, name);
|
b.shader->info->name = ralloc_strdup(b.shader, name);
|
||||||
b.shader->info->cs.local_size[0] = 16;
|
b.shader->info->cs.local_size[0] = 16;
|
||||||
@@ -158,6 +158,44 @@ build_resolve_compute_shader(struct radv_device *dev, bool is_integer, int sampl
|
|||||||
b.cursor = nir_after_cf_node(&outer_if->cf_node);
|
b.cursor = nir_after_cf_node(&outer_if->cf_node);
|
||||||
|
|
||||||
nir_ssa_def *newv = nir_load_var(&b, color);
|
nir_ssa_def *newv = nir_load_var(&b, color);
|
||||||
|
|
||||||
|
if (is_srgb) {
|
||||||
|
nir_const_value v;
|
||||||
|
unsigned i;
|
||||||
|
v.u32[0] = 0x3b4d2e1c; // 0.00313080009
|
||||||
|
|
||||||
|
nir_ssa_def *cmp[3];
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
cmp[i] = nir_flt(&b, nir_channel(&b, newv, i),
|
||||||
|
nir_build_imm(&b, 1, 32, v));
|
||||||
|
|
||||||
|
nir_ssa_def *ltvals[3];
|
||||||
|
v.f32[0] = 12.92;
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
ltvals[i] = nir_fmul(&b, nir_channel(&b, newv, i),
|
||||||
|
nir_build_imm(&b, 1, 32, v));
|
||||||
|
|
||||||
|
nir_ssa_def *gtvals[3];
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
v.f32[0] = 1.0/2.4;
|
||||||
|
gtvals[i] = nir_fpow(&b, nir_channel(&b, newv, i),
|
||||||
|
nir_build_imm(&b, 1, 32, v));
|
||||||
|
v.f32[0] = 1.055;
|
||||||
|
gtvals[i] = nir_fmul(&b, gtvals[i],
|
||||||
|
nir_build_imm(&b, 1, 32, v));
|
||||||
|
v.f32[0] = 0.055;
|
||||||
|
gtvals[i] = nir_fsub(&b, gtvals[i],
|
||||||
|
nir_build_imm(&b, 1, 32, v));
|
||||||
|
}
|
||||||
|
|
||||||
|
nir_ssa_def *comp[4];
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
comp[i] = nir_bcsel(&b, cmp[i], ltvals[i], gtvals[i]);
|
||||||
|
comp[3] = nir_channels(&b, newv, 3);
|
||||||
|
newv = nir_vec(&b, comp, 4);
|
||||||
|
}
|
||||||
|
|
||||||
nir_ssa_def *coord = nir_iadd(&b, global_id, &dst_offset->dest.ssa);
|
nir_ssa_def *coord = nir_iadd(&b, global_id, &dst_offset->dest.ssa);
|
||||||
nir_intrinsic_instr *store = nir_intrinsic_instr_create(b.shader, nir_intrinsic_image_store);
|
nir_intrinsic_instr *store = nir_intrinsic_instr_create(b.shader, nir_intrinsic_image_store);
|
||||||
store->src[0] = nir_src_for_ssa(coord);
|
store->src[0] = nir_src_for_ssa(coord);
|
||||||
@@ -230,12 +268,13 @@ static VkResult
|
|||||||
create_resolve_pipeline(struct radv_device *device,
|
create_resolve_pipeline(struct radv_device *device,
|
||||||
int samples,
|
int samples,
|
||||||
bool is_integer,
|
bool is_integer,
|
||||||
|
bool is_srgb,
|
||||||
VkPipeline *pipeline)
|
VkPipeline *pipeline)
|
||||||
{
|
{
|
||||||
VkResult result;
|
VkResult result;
|
||||||
struct radv_shader_module cs = { .nir = NULL };
|
struct radv_shader_module cs = { .nir = NULL };
|
||||||
|
|
||||||
cs.nir = build_resolve_compute_shader(device, is_integer, samples);
|
cs.nir = build_resolve_compute_shader(device, is_integer, is_srgb, samples);
|
||||||
|
|
||||||
/* compute shader */
|
/* compute shader */
|
||||||
|
|
||||||
@@ -282,12 +321,15 @@ radv_device_init_meta_resolve_compute_state(struct radv_device *device)
|
|||||||
for (uint32_t i = 0; i < MAX_SAMPLES_LOG2; ++i) {
|
for (uint32_t i = 0; i < MAX_SAMPLES_LOG2; ++i) {
|
||||||
uint32_t samples = 1 << i;
|
uint32_t samples = 1 << i;
|
||||||
|
|
||||||
res = create_resolve_pipeline(device, samples, false,
|
res = create_resolve_pipeline(device, samples, false, false,
|
||||||
&state->resolve_compute.rc[i].pipeline);
|
&state->resolve_compute.rc[i].pipeline);
|
||||||
|
|
||||||
res = create_resolve_pipeline(device, samples, true,
|
res = create_resolve_pipeline(device, samples, true, false,
|
||||||
&state->resolve_compute.rc[i].i_pipeline);
|
&state->resolve_compute.rc[i].i_pipeline);
|
||||||
|
|
||||||
|
res = create_resolve_pipeline(device, samples, false, true,
|
||||||
|
&state->resolve_compute.rc[i].srgb_pipeline);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@@ -305,6 +347,10 @@ radv_device_finish_meta_resolve_compute_state(struct radv_device *device)
|
|||||||
radv_DestroyPipeline(radv_device_to_handle(device),
|
radv_DestroyPipeline(radv_device_to_handle(device),
|
||||||
state->resolve_compute.rc[i].i_pipeline,
|
state->resolve_compute.rc[i].i_pipeline,
|
||||||
&state->alloc);
|
&state->alloc);
|
||||||
|
|
||||||
|
radv_DestroyPipeline(radv_device_to_handle(device),
|
||||||
|
state->resolve_compute.rc[i].srgb_pipeline,
|
||||||
|
&state->alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
radv_DestroyDescriptorSetLayout(radv_device_to_handle(device),
|
radv_DestroyDescriptorSetLayout(radv_device_to_handle(device),
|
||||||
@@ -443,6 +489,8 @@ void radv_meta_resolve_compute_image(struct radv_cmd_buffer *cmd_buffer,
|
|||||||
VkPipeline pipeline;
|
VkPipeline pipeline;
|
||||||
if (vk_format_is_int(src_image->vk_format))
|
if (vk_format_is_int(src_image->vk_format))
|
||||||
pipeline = device->meta_state.resolve_compute.rc[samples_log2].i_pipeline;
|
pipeline = device->meta_state.resolve_compute.rc[samples_log2].i_pipeline;
|
||||||
|
else if (vk_format_is_srgb(src_image->vk_format))
|
||||||
|
pipeline = device->meta_state.resolve_compute.rc[samples_log2].srgb_pipeline;
|
||||||
else
|
else
|
||||||
pipeline = device->meta_state.resolve_compute.rc[samples_log2].pipeline;
|
pipeline = device->meta_state.resolve_compute.rc[samples_log2].pipeline;
|
||||||
if (cmd_buffer->state.compute_pipeline != radv_pipeline_from_handle(pipeline)) {
|
if (cmd_buffer->state.compute_pipeline != radv_pipeline_from_handle(pipeline)) {
|
||||||
|
|||||||
@@ -415,6 +415,7 @@ struct radv_meta_state {
|
|||||||
struct {
|
struct {
|
||||||
VkPipeline pipeline;
|
VkPipeline pipeline;
|
||||||
VkPipeline i_pipeline;
|
VkPipeline i_pipeline;
|
||||||
|
VkPipeline srgb_pipeline;
|
||||||
} rc[MAX_SAMPLES_LOG2];
|
} rc[MAX_SAMPLES_LOG2];
|
||||||
} resolve_compute;
|
} resolve_compute;
|
||||||
|
|
||||||
|
|||||||
@@ -396,6 +396,13 @@ vk_format_is_int(VkFormat format)
|
|||||||
return channel >= 0 && desc->channel[channel].pure_integer;
|
return channel >= 0 && desc->channel[channel].pure_integer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
vk_format_is_srgb(VkFormat format)
|
||||||
|
{
|
||||||
|
const struct vk_format_description *desc = vk_format_description(format);
|
||||||
|
return desc->colorspace == VK_FORMAT_COLORSPACE_SRGB;
|
||||||
|
}
|
||||||
|
|
||||||
static inline VkFormat
|
static inline VkFormat
|
||||||
vk_format_stencil_only(VkFormat format)
|
vk_format_stencil_only(VkFormat format)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user