mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-06 01:40:26 +01:00
pvr: workaround hardware clamping for YCBCR_IDENTITY conversion
The TPU clamps to 0..1 so we have to workaround in software on any hardware that does not have XR clamp support. Reviewed-by: Simon Perretta <simon.perretta@imgtec.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39231>
This commit is contained in:
parent
3204e8b1a2
commit
0a01f7aeeb
4 changed files with 158 additions and 0 deletions
|
|
@ -34,6 +34,7 @@ pvr_files = files(
|
|||
'pvr_formats.c',
|
||||
'pvr_image.c',
|
||||
'pvr_instance.c',
|
||||
'pvr_nir_lower_ycbcr.c',
|
||||
'pvr_physical_device.c',
|
||||
'pvr_transfer_frag_store.c',
|
||||
'pvr_query.c',
|
||||
|
|
|
|||
|
|
@ -47,10 +47,12 @@
|
|||
#include "pvr_entrypoints.h"
|
||||
#include "pvr_hw_pass.h"
|
||||
#include "pvr_macros.h"
|
||||
#include "pvr_nir_lower_ycbcr.h"
|
||||
#include "pvr_pass.h"
|
||||
#include "pvr_pds.h"
|
||||
#include "pvr_physical_device.h"
|
||||
#include "pvr_robustness.h"
|
||||
#include "pvr_sampler.h"
|
||||
#include "pvr_types.h"
|
||||
#include "pvr_usc.h"
|
||||
|
||||
|
|
@ -930,6 +932,40 @@ static void pvr_postprocess_shader_data(pco_data *data,
|
|||
struct vk_pipeline_layout *layout,
|
||||
struct usc_mrt_setup *setup);
|
||||
|
||||
struct lower_ycbcr_state {
|
||||
uint32_t set_layout_count;
|
||||
struct vk_descriptor_set_layout *const *set_layouts;
|
||||
};
|
||||
|
||||
static const struct vk_ycbcr_conversion_state *
|
||||
lookup_ycbcr_conversion(const void *_state,
|
||||
uint32_t set,
|
||||
uint32_t binding,
|
||||
uint32_t array_index)
|
||||
{
|
||||
const struct lower_ycbcr_state *state = _state;
|
||||
assert(set < state->set_layout_count);
|
||||
assert(state->set_layouts[set] != NULL);
|
||||
const struct pvr_descriptor_set_layout *set_layout =
|
||||
vk_to_pvr_descriptor_set_layout(state->set_layouts[set]);
|
||||
assert(binding < set_layout->binding_count);
|
||||
|
||||
const struct pvr_descriptor_set_layout_binding *bind_layout =
|
||||
&set_layout->bindings[binding];
|
||||
|
||||
if (bind_layout->immutable_samplers == NULL)
|
||||
return NULL;
|
||||
|
||||
array_index = MIN2(array_index, bind_layout->immutable_sampler_count - 1);
|
||||
|
||||
const struct pvr_sampler *sampler =
|
||||
bind_layout->immutable_samplers[array_index];
|
||||
|
||||
return sampler && sampler->vk.ycbcr_conversion
|
||||
? &sampler->vk.ycbcr_conversion->state
|
||||
: NULL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
Compute pipeline functions
|
||||
******************************************************************************/
|
||||
|
|
@ -983,6 +1019,16 @@ static VkResult pvr_compute_pipeline_compile(
|
|||
layout,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
const struct lower_ycbcr_state ycbcr_state = {
|
||||
.set_layout_count = layout->set_count,
|
||||
.set_layouts = layout->set_layouts,
|
||||
};
|
||||
NIR_PASS(_,
|
||||
nir,
|
||||
nir_pvr_lower_ycbcr_tex,
|
||||
lookup_ycbcr_conversion,
|
||||
&ycbcr_state);
|
||||
pco_lower_nir(pco_ctx, nir, &shader_data);
|
||||
pco_postprocess_nir(pco_ctx, nir, &shader_data);
|
||||
pvr_postprocess_shader_data(&shader_data, nir, pCreateInfo, layout, NULL);
|
||||
|
|
@ -2822,6 +2868,15 @@ pvr_graphics_pipeline_compile(struct pvr_device *const device,
|
|||
state,
|
||||
&mrt_setup);
|
||||
|
||||
const struct lower_ycbcr_state ycbcr_state = {
|
||||
.set_layout_count = layout->set_count,
|
||||
.set_layouts = layout->set_layouts,
|
||||
};
|
||||
NIR_PASS(_,
|
||||
nir_shaders[stage],
|
||||
nir_pvr_lower_ycbcr_tex,
|
||||
lookup_ycbcr_conversion,
|
||||
&ycbcr_state);
|
||||
pco_lower_nir(pco_ctx, nir_shaders[stage], &shader_data[stage]);
|
||||
|
||||
pco_postprocess_nir(pco_ctx, nir_shaders[stage], &shader_data[stage]);
|
||||
|
|
|
|||
80
src/imagination/vulkan/pvr_nir_lower_ycbcr.c
Normal file
80
src/imagination/vulkan/pvr_nir_lower_ycbcr.c
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright © 2026 Imagination Technologies Ltd.
|
||||
* Copyright © 2017 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Based on vk_nir_convert_ycbcr.c.
|
||||
*
|
||||
* We need this to fixup YCBCR_IDENTITY conversion since the TPU clamps the
|
||||
* output from csc into the range 0.0 to 1.0.
|
||||
*/
|
||||
#include "pvr_nir_lower_ycbcr.h"
|
||||
|
||||
#include "nir_builder.h"
|
||||
#include "vk_ycbcr_conversion.h"
|
||||
|
||||
struct lower_ycbcr_tex_state {
|
||||
nir_pvr_ycbcr_conversion_lookup_cb cb;
|
||||
const void *cb_data;
|
||||
};
|
||||
|
||||
static bool
|
||||
lower_ycbcr_tex_instr(nir_builder *b, nir_tex_instr *tex, void *_state)
|
||||
{
|
||||
const struct lower_ycbcr_tex_state *state = _state;
|
||||
|
||||
/* For the following instructions, we don't apply any change and let the
|
||||
* instruction apply to the first plane.
|
||||
*/
|
||||
if (tex->op == nir_texop_txs || tex->op == nir_texop_query_levels ||
|
||||
tex->op == nir_texop_lod)
|
||||
return false;
|
||||
|
||||
int deref_src_idx = nir_tex_instr_src_index(tex, nir_tex_src_texture_deref);
|
||||
assert(deref_src_idx >= 0);
|
||||
nir_deref_instr *deref = nir_src_as_deref(tex->src[deref_src_idx].src);
|
||||
|
||||
nir_variable *var = nir_deref_instr_get_variable(deref);
|
||||
uint32_t set = var->data.descriptor_set;
|
||||
uint32_t binding = var->data.binding;
|
||||
|
||||
assert(tex->texture_index == 0);
|
||||
unsigned array_index = 0;
|
||||
if (deref->deref_type != nir_deref_type_var) {
|
||||
assert(deref->deref_type == nir_deref_type_array);
|
||||
if (!nir_src_is_const(deref->arr.index))
|
||||
return false;
|
||||
array_index = nir_src_as_uint(deref->arr.index);
|
||||
}
|
||||
|
||||
const struct vk_ycbcr_conversion_state *conversion =
|
||||
state->cb(state->cb_data, set, binding, array_index);
|
||||
if (conversion == NULL)
|
||||
return false;
|
||||
|
||||
/* Range expansion fix only needed for YCbCr Identity */
|
||||
if (conversion->ycbcr_model !=
|
||||
VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY)
|
||||
return false;
|
||||
|
||||
b->cursor = nir_after_instr(&tex->instr);
|
||||
nir_def *result =
|
||||
nir_fsub(b, &tex->def, nir_imm_vec4(b, 0.5, 0.0, 0.5, 0.0));
|
||||
nir_def_rewrite_uses_after(&tex->def, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nir_pvr_lower_ycbcr_tex(nir_shader *nir,
|
||||
nir_pvr_ycbcr_conversion_lookup_cb cb,
|
||||
const void *cb_data)
|
||||
{
|
||||
struct lower_ycbcr_tex_state state = {
|
||||
.cb = cb,
|
||||
.cb_data = cb_data,
|
||||
};
|
||||
|
||||
return nir_shader_tex_pass(nir,
|
||||
lower_ycbcr_tex_instr,
|
||||
nir_metadata_control_flow,
|
||||
&state);
|
||||
}
|
||||
22
src/imagination/vulkan/pvr_nir_lower_ycbcr.h
Normal file
22
src/imagination/vulkan/pvr_nir_lower_ycbcr.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright © 2026 Imagination Technologies Ltd.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#ifndef PVR_NIR_LOWER_YCBCR_H
|
||||
#define PVR_NIR_LOWER_YCBCR_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct nir_shader nir_shader;
|
||||
|
||||
typedef const struct vk_ycbcr_conversion_state *(
|
||||
*nir_pvr_ycbcr_conversion_lookup_cb)(const void *data,
|
||||
uint32_t set,
|
||||
uint32_t binding,
|
||||
uint32_t array_index);
|
||||
bool nir_pvr_lower_ycbcr_tex(nir_shader *nir,
|
||||
nir_pvr_ycbcr_conversion_lookup_cb cb,
|
||||
const void *cb_data);
|
||||
|
||||
#endif /* PVR_NIR_LOWER_YCBCR_H */
|
||||
Loading…
Add table
Reference in a new issue