pvr: Add static clear control stream templates in pvr_device.

The templates will be used to flush fragment work at the
pipeline barrier. They will also be used in
vkCmdClearAttachments().

"pds_state" is a pointer to an array. This is done to prevent a
memcpy() patching the PDS state. Whenever the template requires
PDS state we will always be patching it so let's just pass a
pointer instead. Using a pointer here also allows to check (with a
NULL check) whether the pds state in the template was configured
prior to emitting.

Signed-off-by: Karmjit Mahil <Karmjit.Mahil@imgtec.com>
Reviewed-by: Rajnesh Kanwal <rajnesh.kanwal@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18124>
This commit is contained in:
Karmjit Mahil 2022-03-14 16:14:26 +00:00
parent 4eb0991a6f
commit bd02e21885
3 changed files with 204 additions and 1 deletions

View file

@ -154,7 +154,9 @@ SOFTWARE.
<field name="pointlinewidth" start="8" end="15" type="uint">
<define name="SIZE_MAX" value="255"/>
</field>
<field name="sref" start="0" end="7" type="uint"/>
<field name="sref" start="0" end="7" type="uint">
<define name="SIZE_MAX" value="255"/>
</field>
</struct>
<struct name="STATE_ISPB" length="1">
@ -177,6 +179,10 @@ SOFTWARE.
<field name="bottom" start="0" end="8" type="uint"/>
</struct>
<struct name="WCLAMP" length="1">
<field name="val" start="0" end="31" type="uint"/>
</struct>
<struct name="STATE_ISPDBSC" length="1">
<field name="dbindex" start="16" end="31" type="uint"/>
<field name="scindex" start="0" end="15" type="uint"/>
@ -226,6 +232,14 @@ SOFTWARE.
<condition type="endif" check="TEXTURE_WRAP_VARYING"/>
</struct>
<struct name="STATE_VARYING2" length="1">
<field name="output_clip_planes" start="16" end="19" type="uint"/>
<condition type="if" check="TEXTURE_WRAP_VARYING"/>
<field name="f16_npc_wrap" start="8" end="15" type="uint"/>
<field name="f16_linear_wrap" start="0" end="7" type="uint"/>
<condition type="endif" check="TEXTURE_WRAP_VARYING"/>
</struct>
<struct name="STATE_TERMINATE0" length="1">
<field name="clip_right" start="18" end="26" type="uint">
<define name="BLOCK_SIZE_IN_PIXELS" value="32"/>
@ -245,6 +259,14 @@ SOFTWARE.
<field name="render_target" start="0" end="10" type="uint"/>
</struct>
<struct name="STATE_STREAM_OUT0" length="1">
<field name="stream3_size" start="24" end="31" type="uint"/>
<field name="stream2_size" start="16" end="23" type="uint"/>
<field name="stream1_size" start="8" end="15" type="uint"/>
<field name="stream0_mem_output" start="1" end="1" type="bool"/>
<field name="stream0_ta_output" start="0" end="0" type="bool"/>
</struct>
<struct name="STATE_STREAM_OUT1" length="1">
<field name="sync" start="10" end="10" type="bool"/>
<field name="pds_data_size" start="4" end="9" type="uint">

View file

@ -57,6 +57,7 @@
#include "rogue/rogue_compiler.h"
#include "util/build_id.h"
#include "util/log.h"
#include "util/macros.h"
#include "util/mesa-sha1.h"
#include "util/os_misc.h"
#include "util/u_math.h"
@ -1474,6 +1475,104 @@ static void pvr_device_finish_compute_idfwdf_state(struct pvr_device *device)
pvr_bo_free(device, device->idfwdf_state.usc);
}
static void pvr_device_setup_graphics_static_clear_ppp_base(
struct pvr_static_clear_ppp_base *const base)
{
pvr_csb_pack (&base->wclamp, TA_WCLAMP, wclamp) {
wclamp.val = fui(0.00001f);
}
/* clang-format off */
pvr_csb_pack (&base->varying_word[0], TA_STATE_VARYING0, varying0);
pvr_csb_pack (&base->varying_word[1], TA_STATE_VARYING1, varying1);
pvr_csb_pack (&base->varying_word[2], TA_STATE_VARYING2, varying2);
/* clang-format on */
pvr_csb_pack (&base->ppp_ctrl, TA_STATE_PPP_CTRL, ppp_ctrl) {
ppp_ctrl.pretransform = true;
ppp_ctrl.cullmode = PVRX(TA_CULLMODE_NO_CULLING);
}
/* clang-format off */
pvr_csb_pack (&base->stream_out0, TA_STATE_STREAM_OUT0, stream_out0);
/* clang-format on */
}
static void pvr_device_setup_graphics_static_clear_ppp_templates(
struct pvr_static_clear_ppp_template
templates[static PVR_STATIC_CLEAR_VARIANT_COUNT])
{
for (uint32_t i = 0; i < PVR_STATIC_CLEAR_VARIANT_COUNT; i++) {
const bool has_depth = !!(i & PVR_STATIC_CLEAR_DEPTH_BIT);
const bool has_stencil = !!(i & PVR_STATIC_CLEAR_STENCIL_BIT);
const bool has_color = !!(i & PVR_STATIC_CLEAR_COLOR_BIT);
struct pvr_static_clear_ppp_template *const template = &templates[i];
template->requires_pds_state = has_color;
pvr_csb_pack (&template->header, TA_STATE_HEADER, header) {
header.pres_stream_out_size = true;
header.pres_ppp_ctrl = true;
header.pres_varying_word2 = true;
header.pres_varying_word1 = true;
header.pres_varying_word0 = true;
header.pres_outselects = true;
header.pres_wclamp = true;
header.pres_region_clip = true;
header.pres_pds_state_ptr2 = template->requires_pds_state;
header.pres_pds_state_ptr1 = template->requires_pds_state;
header.pres_pds_state_ptr0 = template->requires_pds_state;
header.pres_ispctl_fb = true;
header.pres_ispctl_fa = true;
header.pres_ispctl = true;
}
#define CS_HEADER(cs) \
(struct PVRX(cs)) \
{ \
pvr_cmd_header(cs) \
}
template->config.ispctl = CS_HEADER(TA_STATE_ISPCTL);
template->config.ispctl.tagwritedisable = !has_color;
template->config.ispctl.bpres = true;
template->config.ispa = CS_HEADER(TA_STATE_ISPA);
template->config.ispa.objtype = PVRX(TA_OBJTYPE_TRIANGLE);
template->config.ispa.passtype = PVRX(TA_PASSTYPE_TRANSLUCENT);
template->config.ispa.dwritedisable = !has_depth;
template->config.ispa.dcmpmode = (i == 0) ? PVRX(TA_CMPMODE_NEVER)
: PVRX(TA_CMPMODE_ALWAYS);
template->config.ispa.sref =
has_stencil ? PVRX(TA_STATE_ISPA_SREF_SIZE_MAX) : 0;
pvr_csb_pack (&template->ispb, TA_STATE_ISPB, ispb) {
ispb.scmpmode = PVRX(TA_CMPMODE_ALWAYS);
ispb.sop1 = PVRX(TA_ISPB_STENCILOP_KEEP);
ispb.sop2 = PVRX(TA_ISPB_STENCILOP_KEEP);
ispb.sop3 = has_stencil ? PVRX(TA_ISPB_STENCILOP_REPLACE)
: PVRX(TA_ISPB_STENCILOP_KEEP);
ispb.swmask = has_stencil ? 0xFF : 0;
}
template->config.pds_state = NULL;
template->config.region_clip0 = CS_HEADER(TA_REGION_CLIP0);
template->config.region_clip0.mode = PVRX(TA_REGION_CLIP_MODE_NONE);
template->config.region_clip1 = CS_HEADER(TA_REGION_CLIP1);
template->config.output_sel = CS_HEADER(TA_OUTPUT_SEL);
template->config.output_sel.vtxsize = 4;
template->config.output_sel.rhw_pres = true;
#undef CS_HEADER
}
}
static VkResult
pvr_device_init_graphics_static_clear_state(struct pvr_device *device)
{
@ -1571,6 +1670,9 @@ pvr_device_init_graphics_static_clear_state(struct pvr_device *device)
vk_free(&device->vk.alloc, staging_buffer);
pvr_device_setup_graphics_static_clear_ppp_base(&state->ppp_base);
pvr_device_setup_graphics_static_clear_ppp_templates(state->ppp_templates);
return VK_SUCCESS;
err_free_staging_buffer:

View file

@ -175,6 +175,45 @@ enum pvr_scissor_accum_state {
PVR_SCISSOR_ACCUM_ENABLED,
};
#define PVR_STATIC_CLEAR_PDS_STATE_COUNT \
(pvr_cmd_length(TA_STATE_PDS_SHADERBASE) + \
pvr_cmd_length(TA_STATE_PDS_TEXUNICODEBASE) + \
pvr_cmd_length(TA_STATE_PDS_SIZEINFO1) + \
pvr_cmd_length(TA_STATE_PDS_SIZEINFO2) + \
pvr_cmd_length(TA_STATE_PDS_VARYINGBASE) + \
pvr_cmd_length(TA_STATE_PDS_TEXTUREDATABASE))
/* These can be used as offsets within a PVR_STATIC_CLEAR_PDS_STATE_COUNT dwords
* sized array to get the respective state word.
*
* The values are based on the lengths of the state words.
*/
enum pvr_static_clear_ppp_pds_state_type {
/* Words enabled by pres_pds_state_ptr0. */
PVR_STATIC_CLEAR_PPP_PDS_TYPE_SHADERBASE = 0,
PVR_STATIC_CLEAR_PPP_PDS_TYPE_TEXUNICODEBASE = 1,
PVR_STATIC_CLEAR_PPP_PDS_TYPE_SIZEINFO1 = 2,
PVR_STATIC_CLEAR_PPP_PDS_TYPE_SIZEINFO2 = 3,
/* Word enabled by pres_pds_state_ptr1. */
PVR_STATIC_CLEAR_PPP_PDS_TYPE_VARYINGBASE = 4,
/* Word enabled by pres_pds_state_ptr2. */
PVR_STATIC_CLEAR_PPP_PDS_TYPE_TEXTUREDATABASE = 5,
};
static_assert(PVR_STATIC_CLEAR_PPP_PDS_TYPE_TEXTUREDATABASE + 1 ==
PVR_STATIC_CLEAR_PDS_STATE_COUNT,
"pvr_static_clear_ppp_pds_state_type might require fixing.");
enum pvr_static_clear_variant_bits {
PVR_STATIC_CLEAR_DEPTH_BIT = BITFIELD_BIT(0),
PVR_STATIC_CLEAR_STENCIL_BIT = BITFIELD_BIT(1),
PVR_STATIC_CLEAR_COLOR_BIT = BITFIELD_BIT(2),
};
#define PVR_STATIC_CLEAR_VARIANT_COUNT (PVR_STATIC_CLEAR_COLOR_BIT << 1U)
struct pvr_bo;
struct pvr_compute_ctx;
struct pvr_compute_pipeline;
@ -246,6 +285,42 @@ struct pvr_pds_upload {
uint32_t code_size;
};
struct pvr_static_clear_ppp_base {
uint32_t wclamp;
uint32_t varying_word[3];
uint32_t ppp_ctrl;
uint32_t stream_out0;
};
struct pvr_static_clear_ppp_template {
/* Pre-packed control words. */
uint32_t header;
uint32_t ispb;
bool requires_pds_state;
/* Configurable control words.
* These are initialized and can be modified as needed before emitting them.
*/
struct {
struct PVRX(TA_STATE_ISPCTL) ispctl;
struct PVRX(TA_STATE_ISPA) ispa;
/* In case the template requires_pds_state this needs to be a valid
* pointer to a pre-packed PDS state before emitting.
*
* Note: this is a pointer to an array of const uint32_t and not an array
* of pointers or a function pointer.
*/
const uint32_t (*pds_state)[PVR_STATIC_CLEAR_PDS_STATE_COUNT];
struct PVRX(TA_REGION_CLIP0) region_clip0;
struct PVRX(TA_REGION_CLIP1) region_clip1;
struct PVRX(TA_OUTPUT_SEL) output_sel;
} config;
};
struct pvr_device {
struct vk_device vk;
struct pvr_instance *instance;
@ -297,6 +372,10 @@ struct pvr_device {
struct pvr_bo *usc_vertex_shader_bo;
struct pvr_bo *vertices_bo;
struct pvr_pds_upload pds;
struct pvr_static_clear_ppp_base ppp_base;
struct pvr_static_clear_ppp_template
ppp_templates[PVR_STATIC_CLEAR_VARIANT_COUNT];
} static_clear_state;
VkPhysicalDeviceFeatures features;