mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-22 13:30:12 +01:00
pvr, pco: initial support for blend constants
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
2752a151bf
commit
992ade9e76
6 changed files with 158 additions and 108 deletions
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "common/pvr_limits.h"
|
||||
#include "compiler/shader_enums.h"
|
||||
#include "nir/nir_lower_blend.h"
|
||||
#include "util/format/u_format.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
|
@ -64,11 +65,17 @@ typedef struct _pco_fs_data {
|
|||
/** Fragment output formats. */
|
||||
enum pipe_format output_formats[FRAG_RESULT_MAX];
|
||||
|
||||
/* Blend options. */
|
||||
nir_lower_blend_options blend_opts;
|
||||
pco_range blend_consts;
|
||||
uint8_t blend_consts_needed;
|
||||
|
||||
struct {
|
||||
bool w; /** Whether the shader uses pos.w. */
|
||||
bool z; /** Whether the shader uses pos.z */
|
||||
bool pntc; /** Whether the shader uses point coord. */
|
||||
bool phase_change; /** Whether the shader does a phase change. */
|
||||
bool fbfetch; /** Whether the shader fetches from the framebuffer. */
|
||||
} uses;
|
||||
} pco_fs_data;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
*/
|
||||
|
||||
#include "nir/nir_builder.h"
|
||||
#include "nir/nir_lower_blend.h"
|
||||
#include "pco.h"
|
||||
#include "pco_internal.h"
|
||||
#include "pvr_limits.h"
|
||||
|
|
@ -185,22 +186,31 @@ static bool gather_fs_data_pass(UNUSED struct nir_builder *b,
|
|||
nir_intrinsic_instr *intr,
|
||||
void *cb_data)
|
||||
{
|
||||
/* Check whether the shader accesses z/w. */
|
||||
if (intr->intrinsic != nir_intrinsic_load_input)
|
||||
return false;
|
||||
|
||||
struct nir_io_semantics io_semantics = nir_intrinsic_io_semantics(intr);
|
||||
if (io_semantics.location != VARYING_SLOT_POS)
|
||||
return false;
|
||||
|
||||
unsigned component = nir_intrinsic_component(intr);
|
||||
unsigned chans = intr->def.num_components;
|
||||
assert(component == 2 || chans == 1);
|
||||
|
||||
pco_data *data = cb_data;
|
||||
|
||||
data->fs.uses.z |= (component == 2);
|
||||
data->fs.uses.w |= (component + chans > 3);
|
||||
switch (intr->intrinsic) {
|
||||
/* Check whether the shader accesses z/w. */
|
||||
case nir_intrinsic_load_input: {
|
||||
struct nir_io_semantics io_semantics = nir_intrinsic_io_semantics(intr);
|
||||
if (io_semantics.location != VARYING_SLOT_POS)
|
||||
return false;
|
||||
|
||||
unsigned component = nir_intrinsic_component(intr);
|
||||
unsigned chans = intr->def.num_components;
|
||||
assert(component == 2 || chans == 1);
|
||||
|
||||
data->fs.uses.z |= (component == 2);
|
||||
data->fs.uses.w |= (component + chans > 3);
|
||||
break;
|
||||
}
|
||||
|
||||
case nir_intrinsic_load_blend_const_color_rgba:
|
||||
data->fs.blend_consts_needed |= PIPE_MASK_RGBA;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -225,6 +235,8 @@ static void gather_fs_data(nir_shader *nir, pco_data *data)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
data->fs.uses.fbfetch = nir->info.fs.uses_fbfetch_output;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -704,6 +716,7 @@ void pco_lower_nir(pco_ctx *ctx, nir_shader *nir, pco_data *data)
|
|||
NIR_PASS(_, nir, pco_nir_lower_tex);
|
||||
|
||||
if (nir->info.stage == MESA_SHADER_FRAGMENT) {
|
||||
NIR_PASS(_, nir, nir_lower_blend, &data->fs.blend_opts);
|
||||
NIR_PASS(_, nir, pco_nir_pfo, &data->fs);
|
||||
} else if (nir->info.stage == MESA_SHADER_VERTEX) {
|
||||
NIR_PASS(_,
|
||||
|
|
|
|||
|
|
@ -1131,6 +1131,16 @@ static pco_instr *trans_intr(trans_ctx *tctx, nir_intrinsic_instr *intr)
|
|||
&tctx->shader->data.common.push_consts.range);
|
||||
break;
|
||||
|
||||
case nir_intrinsic_load_blend_const_color_rgba:
|
||||
assert(tctx->stage == MESA_SHADER_FRAGMENT);
|
||||
instr = trans_load_common_store(tctx,
|
||||
intr,
|
||||
dest,
|
||||
pco_ref_null(),
|
||||
false,
|
||||
&tctx->shader->data.fs.blend_consts);
|
||||
break;
|
||||
|
||||
case nir_intrinsic_load_shared:
|
||||
assert(tctx->stage == MESA_SHADER_COMPUTE);
|
||||
instr = trans_load_common_store(tctx,
|
||||
|
|
|
|||
|
|
@ -1574,7 +1574,8 @@ void pvr_pds_generate_descriptor_upload_program(
|
|||
bool halt = last_dma && !input_program->secondary_program_present;
|
||||
|
||||
switch (buffer->type) {
|
||||
case PVR_BUFFER_TYPE_PUSH_CONSTS: {
|
||||
case PVR_BUFFER_TYPE_PUSH_CONSTS:
|
||||
case PVR_BUFFER_TYPE_BLEND_CONSTS: {
|
||||
struct pvr_const_map_entry_special_buffer *special_buffer_entry;
|
||||
|
||||
special_buffer_entry =
|
||||
|
|
|
|||
|
|
@ -3640,6 +3640,26 @@ static VkResult pvr_setup_descriptor_mappings(
|
|||
break;
|
||||
}
|
||||
|
||||
case PVR_BUFFER_TYPE_BLEND_CONSTS: {
|
||||
const struct vk_color_blend_state *cb =
|
||||
&cmd_buffer->vk.dynamic_graphics_state.cb;
|
||||
|
||||
struct pvr_suballoc_bo *blend_consts_bo;
|
||||
result = pvr_cmd_buffer_upload_general(cmd_buffer,
|
||||
cb->blend_constants,
|
||||
sizeof(cb->blend_constants),
|
||||
&blend_consts_bo);
|
||||
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
PVR_WRITE(qword_buffer,
|
||||
blend_consts_bo->dev_addr.addr,
|
||||
special_buff_entry->const_offset,
|
||||
pds_info->data_size_in_dwords);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
UNREACHABLE("Unsupported special buffer type.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "compiler/shader_enums.h"
|
||||
#include "hwdef/rogue_hw_utils.h"
|
||||
#include "nir/nir.h"
|
||||
#include "nir/nir_lower_blend.h"
|
||||
#include "pco/pco.h"
|
||||
#include "pco/pco_data.h"
|
||||
#include "pvr_bo.h"
|
||||
|
|
@ -51,6 +52,7 @@
|
|||
#include "util/u_dynarray.h"
|
||||
#include "util/u_math.h"
|
||||
#include "vk_alloc.h"
|
||||
#include "vk_blend.h"
|
||||
#include "vk_format.h"
|
||||
#include "vk_graphics_state.h"
|
||||
#include "vk_log.h"
|
||||
|
|
@ -588,6 +590,14 @@ static VkResult pvr_pds_descriptor_program_create_and_upload(
|
|||
};
|
||||
}
|
||||
|
||||
if (stage == MESA_SHADER_FRAGMENT && data->fs.blend_consts.count > 0) {
|
||||
program.buffers[program.buffer_count++] = (struct pvr_pds_buffer){
|
||||
.type = PVR_BUFFER_TYPE_BLEND_CONSTS,
|
||||
.size_in_dwords = data->fs.blend_consts.count,
|
||||
.destination = data->fs.blend_consts.start,
|
||||
};
|
||||
}
|
||||
|
||||
pds_info->entries_size_in_bytes = const_entries_size_in_bytes;
|
||||
|
||||
pvr_pds_generate_descriptor_upload_program(&program, NULL, pds_info);
|
||||
|
|
@ -871,16 +881,12 @@ static void pvr_pipeline_finish(struct pvr_device *device,
|
|||
vk_object_base_finish(&pipeline->base);
|
||||
}
|
||||
|
||||
/* How many shared regs it takes to store a pvr_dev_addr_t.
|
||||
* Each shared reg is 32 bits.
|
||||
*/
|
||||
#define PVR_DEV_ADDR_SIZE_IN_SH_REGS \
|
||||
DIV_ROUND_UP(sizeof(pvr_dev_addr_t), sizeof(uint32_t))
|
||||
|
||||
static void pvr_preprocess_shader_data(pco_data *data,
|
||||
nir_shader *nir,
|
||||
const void *pCreateInfo,
|
||||
struct vk_pipeline_layout *layout);
|
||||
static void
|
||||
pvr_preprocess_shader_data(pco_data *data,
|
||||
nir_shader *nir,
|
||||
const void *pCreateInfo,
|
||||
struct vk_pipeline_layout *layout,
|
||||
const struct vk_graphics_pipeline_state *state);
|
||||
|
||||
static void pvr_postprocess_shader_data(pco_data *data,
|
||||
nir_shader *nir,
|
||||
|
|
@ -933,7 +939,7 @@ static VkResult pvr_compute_pipeline_compile(
|
|||
goto err_free_build_context;
|
||||
|
||||
pco_preprocess_nir(pco_ctx, nir);
|
||||
pvr_preprocess_shader_data(&shader_data, nir, pCreateInfo, layout);
|
||||
pvr_preprocess_shader_data(&shader_data, nir, pCreateInfo, layout, NULL);
|
||||
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);
|
||||
|
|
@ -1209,7 +1215,11 @@ static void pvr_fragment_state_save(struct pvr_graphics_pipeline *gfx_pipeline,
|
|||
memcpy(&gfx_pipeline->fs_data, shader_data, sizeof(*shader_data));
|
||||
|
||||
/* TODO: add selection for other values of pass type and sample rate. */
|
||||
fragment_state->pass_type = ROGUE_TA_PASSTYPE_OPAQUE;
|
||||
if (shader_data->fs.uses.fbfetch)
|
||||
fragment_state->pass_type = ROGUE_TA_PASSTYPE_TRANSLUCENT;
|
||||
else
|
||||
fragment_state->pass_type = ROGUE_TA_PASSTYPE_OPAQUE;
|
||||
|
||||
fragment_state->sample_rate = ROGUE_PDSINST_DOUTU_SAMPLE_RATE_INSTANCE;
|
||||
|
||||
/* We can't initialize it yet since we still need to generate the PDS
|
||||
|
|
@ -1218,81 +1228,6 @@ static void pvr_fragment_state_save(struct pvr_graphics_pipeline *gfx_pipeline,
|
|||
fragment_state->stage_state.pds_temps_count = ~0;
|
||||
}
|
||||
|
||||
static bool pvr_blend_factor_requires_consts(VkBlendFactor factor)
|
||||
{
|
||||
switch (factor) {
|
||||
case VK_BLEND_FACTOR_CONSTANT_COLOR:
|
||||
case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR:
|
||||
case VK_BLEND_FACTOR_CONSTANT_ALPHA:
|
||||
case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Indicates whether dynamic blend constants are needed.
|
||||
*
|
||||
* If the user has specified the blend constants to be dynamic, they might not
|
||||
* necessarily be using them. This function makes sure that they are being used
|
||||
* in order to determine whether we need to upload them later on for the shader
|
||||
* to access them.
|
||||
*/
|
||||
static bool pvr_graphics_pipeline_requires_dynamic_blend_consts(
|
||||
const struct pvr_graphics_pipeline *gfx_pipeline)
|
||||
{
|
||||
const struct vk_dynamic_graphics_state *const state =
|
||||
&gfx_pipeline->dynamic_state;
|
||||
|
||||
if (BITSET_TEST(state->set, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS))
|
||||
return false;
|
||||
|
||||
for (uint32_t i = 0; i < state->cb.attachment_count; i++) {
|
||||
const struct vk_color_blend_attachment_state *attachment =
|
||||
&state->cb.attachments[i];
|
||||
|
||||
const bool has_color_write =
|
||||
attachment->write_mask &
|
||||
(VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
|
||||
VK_COLOR_COMPONENT_B_BIT);
|
||||
const bool has_alpha_write = attachment->write_mask &
|
||||
VK_COLOR_COMPONENT_A_BIT;
|
||||
|
||||
if (!attachment->blend_enable || attachment->write_mask == 0)
|
||||
continue;
|
||||
|
||||
if (has_color_write) {
|
||||
const uint8_t src_color_blend_factor =
|
||||
attachment->src_color_blend_factor;
|
||||
const uint8_t dst_color_blend_factor =
|
||||
attachment->dst_color_blend_factor;
|
||||
|
||||
if (pvr_blend_factor_requires_consts(src_color_blend_factor) ||
|
||||
pvr_blend_factor_requires_consts(dst_color_blend_factor)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_alpha_write) {
|
||||
const uint8_t src_alpha_blend_factor =
|
||||
attachment->src_alpha_blend_factor;
|
||||
const uint8_t dst_alpha_blend_factor =
|
||||
attachment->dst_alpha_blend_factor;
|
||||
|
||||
if (pvr_blend_factor_requires_consts(src_alpha_blend_factor) ||
|
||||
pvr_blend_factor_requires_consts(dst_alpha_blend_factor)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#undef PVR_DEV_ADDR_SIZE_IN_SH_REGS
|
||||
|
||||
static void pvr_graphics_pipeline_setup_vertex_dma(
|
||||
struct pvr_graphics_pipeline *gfx_pipeline,
|
||||
const VkPipelineVertexInputStateCreateInfo *const vertex_input_state,
|
||||
|
|
@ -1916,6 +1851,51 @@ static void pvr_init_fs_input_attachments(
|
|||
pvr_finishme("pvr_init_fs_input_attachments");
|
||||
}
|
||||
|
||||
static void pvr_init_fs_blend(pco_data *data,
|
||||
const struct vk_color_blend_state *cb)
|
||||
{
|
||||
nir_lower_blend_options *blend_opts = &data->fs.blend_opts;
|
||||
if (!cb)
|
||||
return;
|
||||
|
||||
blend_opts->logicop_enable = cb->logic_op_enable;
|
||||
blend_opts->logicop_func = vk_logic_op_to_pipe(cb->logic_op);
|
||||
|
||||
unsigned count = cb->attachment_count;
|
||||
for (unsigned u = 0; u < count; ++u) {
|
||||
const struct vk_color_blend_attachment_state *rt = &cb->attachments[u];
|
||||
gl_frag_result location = FRAG_RESULT_DATA0 + u;
|
||||
blend_opts->format[u] = data->fs.output_formats[location];
|
||||
|
||||
if (cb->logic_op_enable) {
|
||||
/* No blending, but we get the colour mask below */
|
||||
} else if (!rt->blend_enable) {
|
||||
const nir_lower_blend_channel replace = {
|
||||
.func = PIPE_BLEND_ADD,
|
||||
.src_factor = PIPE_BLENDFACTOR_ONE,
|
||||
.dst_factor = PIPE_BLENDFACTOR_ZERO,
|
||||
};
|
||||
|
||||
blend_opts->rt[u].rgb = replace;
|
||||
blend_opts->rt[u].alpha = replace;
|
||||
} else {
|
||||
blend_opts->rt[u].rgb.func = vk_blend_op_to_pipe(rt->color_blend_op);
|
||||
blend_opts->rt[u].rgb.src_factor =
|
||||
vk_blend_factor_to_pipe(rt->src_color_blend_factor);
|
||||
blend_opts->rt[u].rgb.dst_factor =
|
||||
vk_blend_factor_to_pipe(rt->dst_color_blend_factor);
|
||||
|
||||
blend_opts->rt[u].alpha.func = vk_blend_op_to_pipe(rt->alpha_blend_op);
|
||||
blend_opts->rt[u].alpha.src_factor =
|
||||
vk_blend_factor_to_pipe(rt->src_alpha_blend_factor);
|
||||
blend_opts->rt[u].alpha.dst_factor =
|
||||
vk_blend_factor_to_pipe(rt->dst_alpha_blend_factor);
|
||||
}
|
||||
|
||||
blend_opts->rt[u].colormask = rt->write_mask;
|
||||
}
|
||||
}
|
||||
|
||||
static void pvr_setup_fs_input_attachments(
|
||||
pco_data *data,
|
||||
nir_shader *nir,
|
||||
|
|
@ -1925,6 +1905,20 @@ static void pvr_setup_fs_input_attachments(
|
|||
pvr_finishme("pvr_setup_fs_input_attachments");
|
||||
}
|
||||
|
||||
static void pvr_setup_fs_blend(pco_data *data)
|
||||
{
|
||||
unsigned num_blend_consts = util_bitcount(data->fs.blend_consts_needed);
|
||||
if (!num_blend_consts)
|
||||
return;
|
||||
|
||||
data->fs.blend_consts = (pco_range){
|
||||
.start = data->common.shareds,
|
||||
.count = num_blend_consts,
|
||||
};
|
||||
|
||||
data->common.shareds += num_blend_consts;
|
||||
}
|
||||
|
||||
static void pvr_alloc_cs_sysvals(pco_data *data, nir_shader *nir)
|
||||
{
|
||||
BITSET_DECLARE(system_values_read, SYSTEM_VALUE_MAX);
|
||||
|
|
@ -2087,10 +2081,12 @@ static void pvr_setup_descriptors(pco_data *data,
|
|||
assert(data->common.shareds < 256);
|
||||
}
|
||||
|
||||
static void pvr_preprocess_shader_data(pco_data *data,
|
||||
nir_shader *nir,
|
||||
const void *pCreateInfo,
|
||||
struct vk_pipeline_layout *layout)
|
||||
static void
|
||||
pvr_preprocess_shader_data(pco_data *data,
|
||||
nir_shader *nir,
|
||||
const void *pCreateInfo,
|
||||
struct vk_pipeline_layout *layout,
|
||||
const struct vk_graphics_pipeline_state *state)
|
||||
{
|
||||
const VkGraphicsPipelineCreateInfo *pGraphicsCreateInfo = pCreateInfo;
|
||||
|
||||
|
|
@ -2115,8 +2111,9 @@ static void pvr_preprocess_shader_data(pco_data *data,
|
|||
|
||||
pvr_init_fs_outputs(data, pass, subpass, hw_subpass);
|
||||
pvr_init_fs_input_attachments(data, subpass, hw_subpass);
|
||||
pvr_init_fs_blend(data, state->cb);
|
||||
|
||||
/* TODO: push consts, blend consts, dynamic state, etc. */
|
||||
/* TODO: push consts, dynamic state, etc. */
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -2162,6 +2159,7 @@ static void pvr_postprocess_shader_data(pco_data *data,
|
|||
pvr_alloc_fs_varyings(data, nir);
|
||||
pvr_setup_fs_outputs(data, nir, subpass, hw_subpass);
|
||||
pvr_setup_fs_input_attachments(data, nir, subpass, hw_subpass);
|
||||
pvr_setup_fs_blend(data);
|
||||
|
||||
/* TODO: push consts, blend consts, dynamic state, etc. */
|
||||
break;
|
||||
|
|
@ -2268,7 +2266,8 @@ pvr_graphics_pipeline_compile(struct pvr_device *const device,
|
|||
pvr_preprocess_shader_data(&shader_data[stage],
|
||||
nir_shaders[stage],
|
||||
pCreateInfo,
|
||||
layout);
|
||||
layout,
|
||||
state);
|
||||
|
||||
pco_lower_nir(pco_ctx, nir_shaders[stage], &shader_data[stage]);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue