summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2017-04-20 04:42:26 +0100
committerDave Airlie <[email protected]>2017-05-07 23:41:38 +0100
commit588185eb6b76bf31fedbfcbf32fc3b2035b2d541 (patch)
tree8a20108054710b852a2861f28177a1aa7b52e993
parentdab6a2dfd9cab05e7e9b57373546516bf153f080 (diff)
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 <[email protected]> Signed-off-by: Dave Airlie <[email protected]>
-rw-r--r--src/amd/vulkan/radv_meta_resolve_cs.c58
-rw-r--r--src/amd/vulkan/radv_private.h1
-rw-r--r--src/amd/vulkan/vk_format.h7
3 files changed, 61 insertions, 5 deletions
diff --git a/src/amd/vulkan/radv_meta_resolve_cs.c b/src/amd/vulkan/radv_meta_resolve_cs.c
index dc4a1bb53d1..99a3a06381c 100644
--- a/src/amd/vulkan/radv_meta_resolve_cs.c
+++ b/src/amd/vulkan/radv_meta_resolve_cs.c
@@ -32,7 +32,7 @@
#include "vk_format.h"
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;
char name[64];
@@ -45,7 +45,7 @@ build_resolve_compute_shader(struct radv_device *dev, bool is_integer, int sampl
false,
false,
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);
b.shader->info->name = ralloc_strdup(b.shader, name);
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);
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_intrinsic_instr *store = nir_intrinsic_instr_create(b.shader, nir_intrinsic_image_store);
store->src[0] = nir_src_for_ssa(coord);
@@ -230,12 +268,13 @@ static VkResult
create_resolve_pipeline(struct radv_device *device,
int samples,
bool is_integer,
+ bool is_srgb,
VkPipeline *pipeline)
{
VkResult result;
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 */
@@ -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) {
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);
- res = create_resolve_pipeline(device, samples, true,
+ res = create_resolve_pipeline(device, samples, true, false,
&state->resolve_compute.rc[i].i_pipeline);
+ res = create_resolve_pipeline(device, samples, false, true,
+ &state->resolve_compute.rc[i].srgb_pipeline);
+
}
return res;
@@ -305,6 +347,10 @@ radv_device_finish_meta_resolve_compute_state(struct radv_device *device)
radv_DestroyPipeline(radv_device_to_handle(device),
state->resolve_compute.rc[i].i_pipeline,
&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),
@@ -443,6 +489,8 @@ void radv_meta_resolve_compute_image(struct radv_cmd_buffer *cmd_buffer,
VkPipeline pipeline;
if (vk_format_is_int(src_image->vk_format))
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
pipeline = device->meta_state.resolve_compute.rc[samples_log2].pipeline;
if (cmd_buffer->state.compute_pipeline != radv_pipeline_from_handle(pipeline)) {
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index 1fe54bb8a07..a02310b2644 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -415,6 +415,7 @@ struct radv_meta_state {
struct {
VkPipeline pipeline;
VkPipeline i_pipeline;
+ VkPipeline srgb_pipeline;
} rc[MAX_SAMPLES_LOG2];
} resolve_compute;
diff --git a/src/amd/vulkan/vk_format.h b/src/amd/vulkan/vk_format.h
index 13ac1793460..af71e29f6ad 100644
--- a/src/amd/vulkan/vk_format.h
+++ b/src/amd/vulkan/vk_format.h
@@ -396,6 +396,13 @@ vk_format_is_int(VkFormat format)
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
vk_format_stencil_only(VkFormat format)
{