mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 04:20:08 +01:00
pvr, pco: improved image write (with format) support, handle 111110
Signed-off-by: Simon Perretta <simon.perretta@imgtec.com> Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36412>
This commit is contained in:
parent
fe884e30f8
commit
78062fbb75
4 changed files with 285 additions and 1 deletions
|
|
@ -112,6 +112,16 @@ pack_snorm_1x8(float x)
|
|||
_mesa_roundevenf(CLAMP(x, -1.0f, +1.0f) * 127.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate component [0,2] of packSnorm3x10_1x2.
|
||||
*/
|
||||
static uint16_t
|
||||
pack_snorm_1x10(float x)
|
||||
{
|
||||
return (uint16_t) (int)
|
||||
_mesa_roundevenf(CLAMP(x, -1.0f, +1.0f) * 511.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate one component of packSnorm2x16.
|
||||
*/
|
||||
|
|
@ -152,6 +162,16 @@ unpack_snorm_1x8(uint8_t u)
|
|||
return CLAMP((int8_t) u / 127.0f, -1.0f, +1.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate component [0,2] of unpackSnorm3x10_1x2.
|
||||
*/
|
||||
static float
|
||||
unpack_snorm_1x10(uint16_t u)
|
||||
{
|
||||
u &= 0x03FF;
|
||||
return CLAMP((int16_t) u / 511.0f, -1.0f, +1.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate one component of unpackSnorm2x16.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1846,12 +1846,23 @@ pack_rg("unorm", 8, 8)
|
|||
pack_rgb("snorm", 8, 8, 8)
|
||||
pack_rgb("unorm", 8, 8, 8)
|
||||
|
||||
pack_r("snorm", 10)
|
||||
pack_r("unorm", 10)
|
||||
|
||||
pack_r("snorm", 16)
|
||||
pack_r("unorm", 16)
|
||||
pack_r("half", 16)
|
||||
|
||||
pack_rgba("unorm", 10, 10, 10, 2)
|
||||
|
||||
unop_horiz(f"pack_float_10", 1, tuint32, 1, tfloat32, f"""
|
||||
dst.x = f32_to_uf10(src0.x) & 0x3ff;
|
||||
""")
|
||||
|
||||
unop_horiz(f"pack_float_11", 1, tuint32, 1, tfloat32, f"""
|
||||
dst.x = f32_to_uf11(src0.x) & 0x7ff;
|
||||
""")
|
||||
|
||||
unop_horiz(f"pack_float_11_11_10", 1, tuint32, 3, tfloat32, f"""
|
||||
dst.x = f32_to_uf11(src0.x) & 0x7ff;
|
||||
dst.x |= (f32_to_uf11(src0.y) & 0x7ff) << 11;
|
||||
|
|
|
|||
|
|
@ -717,6 +717,39 @@ bool pco_nir_lower_tex(nir_shader *shader)
|
|||
return nir_shader_lower_instructions(shader, is_tex, lower_tex, NULL);
|
||||
}
|
||||
|
||||
static enum util_format_type nir_type_to_util_type(nir_alu_type nir_type)
|
||||
{
|
||||
switch (nir_alu_type_get_base_type(nir_type)) {
|
||||
case nir_type_int:
|
||||
return UTIL_FORMAT_TYPE_SIGNED;
|
||||
|
||||
case nir_type_uint:
|
||||
return UTIL_FORMAT_TYPE_UNSIGNED;
|
||||
|
||||
case nir_type_float:
|
||||
return UTIL_FORMAT_TYPE_FLOAT;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UNREACHABLE("Unsupported nir_alu_type.");
|
||||
}
|
||||
|
||||
static enum pipe_format nir_type_to_pipe_format(nir_alu_type nir_type,
|
||||
unsigned num_components)
|
||||
{
|
||||
enum util_format_type format_type = nir_type_to_util_type(nir_type);
|
||||
unsigned bits = nir_alu_type_get_type_size(nir_type);
|
||||
bool pure_integer = format_type != UTIL_FORMAT_TYPE_FLOAT;
|
||||
|
||||
return util_format_get_array(format_type,
|
||||
bits,
|
||||
num_components,
|
||||
false,
|
||||
pure_integer);
|
||||
}
|
||||
|
||||
static nir_def *lower_image(nir_builder *b, nir_instr *instr, void *cb_data)
|
||||
{
|
||||
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
|
||||
|
|
@ -728,6 +761,24 @@ static nir_def *lower_image(nir_builder *b, nir_instr *instr, void *cb_data)
|
|||
unsigned binding = nir_src_comp_as_uint(intr->src[0], 1);
|
||||
nir_def *elem = nir_channel(b, intr->src[0].ssa, 2);
|
||||
|
||||
nir_def *lod;
|
||||
switch (intr->intrinsic) {
|
||||
case nir_intrinsic_image_deref_load:
|
||||
lod = intr->src[3].ssa;
|
||||
break;
|
||||
|
||||
case nir_intrinsic_image_deref_store:
|
||||
lod = intr->src[4].ssa;
|
||||
break;
|
||||
|
||||
case nir_intrinsic_image_deref_size:
|
||||
lod = intr->src[1].ssa;
|
||||
break;
|
||||
|
||||
default:
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
if (intr->intrinsic == nir_intrinsic_image_deref_size) {
|
||||
if (image_dim == GLSL_SAMPLER_DIM_BUF) {
|
||||
assert(intr->def.num_components == 1);
|
||||
|
|
@ -764,7 +815,6 @@ static nir_def *lower_image(nir_builder *b, nir_instr *instr, void *cb_data)
|
|||
};
|
||||
|
||||
nir_def *base_level = STATE_UNPACK(b, tex_state_word, 3, 28, 4);
|
||||
nir_def *lod = intr->src[0].ssa;
|
||||
lod = nir_iadd(b, lod, base_level);
|
||||
|
||||
for (unsigned c = 0; c < num_comps; ++c)
|
||||
|
|
@ -795,6 +845,173 @@ static nir_def *lower_image(nir_builder *b, nir_instr *instr, void *cb_data)
|
|||
if (write_data) {
|
||||
assert(intr->num_components == 4);
|
||||
assert(write_data->num_components == 4);
|
||||
|
||||
/* TODO: formatless write support */
|
||||
assert(format != PIPE_FORMAT_NONE);
|
||||
|
||||
const struct util_format_description *desc =
|
||||
util_format_description(format);
|
||||
|
||||
enum pipe_format data_format =
|
||||
nir_type_to_pipe_format(type, desc->nr_channels);
|
||||
|
||||
/* TODO: u/sint need clamping? */
|
||||
|
||||
if (format != data_format) {
|
||||
nir_def *write_data_comps[4];
|
||||
for (unsigned c = 0; c < desc->nr_channels; ++c) {
|
||||
enum pipe_swizzle chan = desc->swizzle[c];
|
||||
nir_def *input = nir_channel(b, write_data, c);
|
||||
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_R8_UINT:
|
||||
case PIPE_FORMAT_R8G8_UINT:
|
||||
case PIPE_FORMAT_R8G8B8_UINT:
|
||||
case PIPE_FORMAT_R8G8B8A8_UINT:
|
||||
|
||||
case PIPE_FORMAT_R8_SINT:
|
||||
case PIPE_FORMAT_R8G8_SINT:
|
||||
case PIPE_FORMAT_R8G8B8_SINT:
|
||||
case PIPE_FORMAT_R8G8B8A8_SINT:
|
||||
write_data_comps[chan] =
|
||||
nir_bitfield_insert_imm(b, nir_imm_int(b, 0), input, 0, 8);
|
||||
break;
|
||||
|
||||
case PIPE_FORMAT_R8_UNORM:
|
||||
case PIPE_FORMAT_R8G8_UNORM:
|
||||
case PIPE_FORMAT_R8G8B8_UNORM:
|
||||
case PIPE_FORMAT_R8G8B8A8_UNORM:
|
||||
write_data_comps[chan] = nir_pack_unorm_8(b, input);
|
||||
break;
|
||||
|
||||
case PIPE_FORMAT_R8_SNORM:
|
||||
case PIPE_FORMAT_R8G8_SNORM:
|
||||
case PIPE_FORMAT_R8G8B8_SNORM:
|
||||
case PIPE_FORMAT_R8G8B8A8_SNORM:
|
||||
write_data_comps[chan] = nir_pack_snorm_8(b, input);
|
||||
break;
|
||||
|
||||
case PIPE_FORMAT_R11G11B10_FLOAT:
|
||||
switch (chan) {
|
||||
case PIPE_SWIZZLE_X:
|
||||
case PIPE_SWIZZLE_Y:
|
||||
write_data_comps[chan] = nir_pack_float_11(b, input);
|
||||
break;
|
||||
|
||||
case PIPE_SWIZZLE_Z:
|
||||
write_data_comps[chan] = nir_pack_float_10(b, input);
|
||||
break;
|
||||
|
||||
default:
|
||||
UNREACHABLE("");
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_FORMAT_R10G10B10A2_UINT:
|
||||
|
||||
case PIPE_FORMAT_R10G10B10A2_SINT:
|
||||
|
||||
switch (chan) {
|
||||
case PIPE_SWIZZLE_X:
|
||||
case PIPE_SWIZZLE_Y:
|
||||
case PIPE_SWIZZLE_Z:
|
||||
write_data_comps[chan] =
|
||||
nir_bitfield_insert_imm(b, nir_imm_int(b, 0), input, 0, 10);
|
||||
break;
|
||||
|
||||
case PIPE_SWIZZLE_W:
|
||||
write_data_comps[chan] =
|
||||
nir_bitfield_insert_imm(b, nir_imm_int(b, 0), input, 0, 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
UNREACHABLE("");
|
||||
}
|
||||
break;
|
||||
|
||||
/* TODO: better way to do the 1x2 component. */
|
||||
case PIPE_FORMAT_R10G10B10A2_UNORM:
|
||||
switch (chan) {
|
||||
case PIPE_SWIZZLE_X:
|
||||
case PIPE_SWIZZLE_Y:
|
||||
case PIPE_SWIZZLE_Z:
|
||||
write_data_comps[chan] = nir_pack_unorm_10(b, input);
|
||||
break;
|
||||
|
||||
case PIPE_SWIZZLE_W:
|
||||
write_data_comps[chan] =
|
||||
nir_f2i32_rtne(b,
|
||||
nir_fmul_imm(b, nir_fsat(b, input), 3.0f));
|
||||
break;
|
||||
|
||||
default:
|
||||
UNREACHABLE("");
|
||||
}
|
||||
break;
|
||||
|
||||
/* TODO: better way to do the 1x2 component. */
|
||||
case PIPE_FORMAT_R10G10B10A2_SNORM:
|
||||
switch (chan) {
|
||||
case PIPE_SWIZZLE_X:
|
||||
case PIPE_SWIZZLE_Y:
|
||||
case PIPE_SWIZZLE_Z:
|
||||
write_data_comps[chan] = nir_pack_snorm_10(b, input);
|
||||
break;
|
||||
|
||||
case PIPE_SWIZZLE_W:
|
||||
write_data_comps[chan] =
|
||||
nir_f2i32_rtne(b, nir_fsat_signed(b, input));
|
||||
break;
|
||||
|
||||
default:
|
||||
UNREACHABLE("");
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_FORMAT_R16_UINT:
|
||||
case PIPE_FORMAT_R16G16_UINT:
|
||||
case PIPE_FORMAT_R16G16B16_UINT:
|
||||
case PIPE_FORMAT_R16G16B16A16_UINT:
|
||||
|
||||
case PIPE_FORMAT_R16_SINT:
|
||||
case PIPE_FORMAT_R16G16_SINT:
|
||||
case PIPE_FORMAT_R16G16B16_SINT:
|
||||
case PIPE_FORMAT_R16G16B16A16_SINT:
|
||||
write_data_comps[chan] =
|
||||
nir_bitfield_insert_imm(b, nir_imm_int(b, 0), input, 0, 16);
|
||||
break;
|
||||
|
||||
case PIPE_FORMAT_R16_FLOAT:
|
||||
case PIPE_FORMAT_R16G16_FLOAT:
|
||||
case PIPE_FORMAT_R16G16B16_FLOAT:
|
||||
case PIPE_FORMAT_R16G16B16A16_FLOAT:
|
||||
write_data_comps[chan] = nir_pack_half_16(b, input);
|
||||
break;
|
||||
|
||||
case PIPE_FORMAT_R16_UNORM:
|
||||
case PIPE_FORMAT_R16G16_UNORM:
|
||||
case PIPE_FORMAT_R16G16B16_UNORM:
|
||||
case PIPE_FORMAT_R16G16B16A16_UNORM:
|
||||
write_data_comps[chan] = nir_pack_unorm_16(b, input);
|
||||
break;
|
||||
|
||||
case PIPE_FORMAT_R16_SNORM:
|
||||
case PIPE_FORMAT_R16G16_SNORM:
|
||||
case PIPE_FORMAT_R16G16B16_SNORM:
|
||||
case PIPE_FORMAT_R16G16B16A16_SNORM:
|
||||
write_data_comps[chan] = nir_pack_snorm_16(b, input);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unsupported image write pack format %s.\n",
|
||||
util_format_name(format));
|
||||
UNREACHABLE("");
|
||||
}
|
||||
}
|
||||
|
||||
write_data = nir_vec(b, write_data_comps, desc->nr_channels);
|
||||
write_data = nir_pad_vector(b, write_data, 4);
|
||||
}
|
||||
}
|
||||
|
||||
bool ia = image_dim == GLSL_SAMPLER_DIM_SUBPASS ||
|
||||
|
|
@ -867,6 +1084,8 @@ static nir_def *lower_image(nir_builder *b, nir_instr *instr, void *cb_data)
|
|||
|
||||
.write_data = write_data,
|
||||
|
||||
.lod_replace = lod,
|
||||
|
||||
.sample_components = intr->intrinsic == nir_intrinsic_image_deref_load
|
||||
? intr->def.num_components
|
||||
: 0,
|
||||
|
|
|
|||
|
|
@ -2528,6 +2528,40 @@ static pco_instr *trans_alu(trans_ctx *tctx, nir_alu_instr *alu)
|
|||
.scale = true);
|
||||
break;
|
||||
|
||||
case nir_op_pack_unorm_10:
|
||||
instr = pco_pck(&tctx->b,
|
||||
dest,
|
||||
src[0],
|
||||
.rpt = 1,
|
||||
.pck_fmt = PCO_PCK_FMT_U1010102,
|
||||
.scale = true);
|
||||
break;
|
||||
|
||||
case nir_op_pack_snorm_10:
|
||||
instr = pco_pck(&tctx->b,
|
||||
dest,
|
||||
src[0],
|
||||
.rpt = 1,
|
||||
.pck_fmt = PCO_PCK_FMT_S1010102,
|
||||
.scale = true);
|
||||
break;
|
||||
|
||||
case nir_op_pack_float_10:
|
||||
instr = pco_pck(&tctx->b,
|
||||
dest,
|
||||
src[0],
|
||||
.rpt = 1,
|
||||
.pck_fmt = PCO_PCK_FMT_2F10F10F10);
|
||||
break;
|
||||
|
||||
case nir_op_pack_float_11:
|
||||
instr = pco_pck(&tctx->b,
|
||||
dest,
|
||||
src[0],
|
||||
.rpt = 1,
|
||||
.pck_fmt = PCO_PCK_FMT_F111110);
|
||||
break;
|
||||
|
||||
case nir_op_pack_float_11_11_10:
|
||||
instr = pco_pck(&tctx->b,
|
||||
dest,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue