mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 05:18:08 +02:00
pvr: Move static clear state into pvr_clear.c .
Signed-off-by: Karmjit Mahil <Karmjit.Mahil@imgtec.com> Reviewed-by: Frank Binns <frank.binns@imgtec.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20055>
This commit is contained in:
parent
aa37415f1c
commit
13fc4b1780
4 changed files with 406 additions and 401 deletions
|
|
@ -24,12 +24,333 @@
|
|||
#include <stdint.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include "hwdef/rogue_hw_utils.h"
|
||||
#include "pvr_clear.h"
|
||||
#include "pvr_hardcode.h"
|
||||
#include "pvr_pds.h"
|
||||
#include "pvr_private.h"
|
||||
#include "vk_alloc.h"
|
||||
#include "vk_log.h"
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Emit geom state from a configurable template.
|
||||
*
|
||||
* Note that the state is emitted by joining the template with a base so the
|
||||
* base must have been setup before calling this.
|
||||
*
|
||||
* \param[in] csb Control stream to emit to.
|
||||
* \param[in] template The configured template.
|
||||
* \param[out] pvr_bo_out Uploaded state's pvr_bo object.
|
||||
*
|
||||
* \return VK_SUCCESS if the state was successfully uploaded.
|
||||
*/
|
||||
VkResult pvr_emit_ppp_from_template(
|
||||
struct pvr_csb *const csb,
|
||||
const struct pvr_static_clear_ppp_template *const template,
|
||||
struct pvr_bo **const pvr_bo_out)
|
||||
{
|
||||
const uint32_t dword_count =
|
||||
pvr_cmd_length(TA_STATE_HEADER) + pvr_cmd_length(TA_STATE_ISPCTL) +
|
||||
pvr_cmd_length(TA_STATE_ISPA) + pvr_cmd_length(TA_STATE_ISPB) +
|
||||
(template->requires_pds_state ? PVR_STATIC_CLEAR_PDS_STATE_COUNT : 0) +
|
||||
pvr_cmd_length(TA_REGION_CLIP0) + pvr_cmd_length(TA_REGION_CLIP1) +
|
||||
pvr_cmd_length(TA_WCLAMP) + pvr_cmd_length(TA_OUTPUT_SEL) +
|
||||
pvr_cmd_length(TA_STATE_VARYING0) + pvr_cmd_length(TA_STATE_VARYING1) +
|
||||
pvr_cmd_length(TA_STATE_VARYING2) + pvr_cmd_length(TA_STATE_PPP_CTRL) +
|
||||
pvr_cmd_length(TA_STATE_STREAM_OUT0);
|
||||
|
||||
struct pvr_device *const device = csb->device;
|
||||
const uint32_t cache_line_size =
|
||||
rogue_get_slc_cache_line_size(&device->pdevice->dev_info);
|
||||
const struct pvr_static_clear_ppp_base *const base =
|
||||
&device->static_clear_state.ppp_base;
|
||||
struct pvr_bo *pvr_bo;
|
||||
uint32_t *stream;
|
||||
VkResult result;
|
||||
|
||||
result = pvr_bo_alloc(device,
|
||||
device->heaps.general_heap,
|
||||
dword_count * sizeof(uint32_t),
|
||||
cache_line_size,
|
||||
PVR_BO_ALLOC_FLAG_CPU_MAPPED,
|
||||
&pvr_bo);
|
||||
if (result != VK_SUCCESS) {
|
||||
*pvr_bo_out = NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
stream = (uint32_t *)pvr_bo->bo->map;
|
||||
|
||||
pvr_csb_write_value(stream, TA_STATE_HEADER, template->header);
|
||||
pvr_csb_write_struct(stream, TA_STATE_ISPCTL, &template->config.ispctl);
|
||||
pvr_csb_write_struct(stream, TA_STATE_ISPA, &template->config.ispa);
|
||||
pvr_csb_write_value(stream, TA_STATE_ISPB, template->ispb);
|
||||
|
||||
if (template->requires_pds_state) {
|
||||
static_assert(sizeof(*stream) == sizeof((*template->config.pds_state)[0]),
|
||||
"Size mismatch");
|
||||
for (uint32_t i = 0; i < PVR_STATIC_CLEAR_PDS_STATE_COUNT; i++)
|
||||
*stream++ = (*template->config.pds_state)[i];
|
||||
}
|
||||
|
||||
pvr_csb_write_struct(stream,
|
||||
TA_REGION_CLIP0,
|
||||
&template->config.region_clip0);
|
||||
pvr_csb_write_struct(stream,
|
||||
TA_REGION_CLIP1,
|
||||
&template->config.region_clip1);
|
||||
pvr_csb_write_value(stream, TA_WCLAMP, base->wclamp);
|
||||
pvr_csb_write_struct(stream, TA_OUTPUT_SEL, &template->config.output_sel);
|
||||
pvr_csb_write_value(stream, TA_STATE_VARYING0, base->varying_word[0]);
|
||||
pvr_csb_write_value(stream, TA_STATE_VARYING1, base->varying_word[1]);
|
||||
pvr_csb_write_value(stream, TA_STATE_VARYING2, base->varying_word[2]);
|
||||
pvr_csb_write_value(stream, TA_STATE_PPP_CTRL, base->ppp_ctrl);
|
||||
pvr_csb_write_value(stream, TA_STATE_STREAM_OUT0, base->stream_out0);
|
||||
|
||||
assert((uint64_t)(stream - (uint32_t *)pvr_bo->bo->map) == dword_count);
|
||||
|
||||
pvr_bo_cpu_unmap(device, pvr_bo);
|
||||
stream = NULL;
|
||||
|
||||
pvr_csb_emit (csb, VDMCTRL_PPP_STATE0, state) {
|
||||
state.word_count = dword_count;
|
||||
state.addrmsb = pvr_bo->vma->dev_addr;
|
||||
}
|
||||
|
||||
pvr_csb_emit (csb, VDMCTRL_PPP_STATE1, state) {
|
||||
state.addrlsb = pvr_bo->vma->dev_addr;
|
||||
}
|
||||
|
||||
*pvr_bo_out = pvr_bo;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult pvr_device_init_graphics_static_clear_state(struct pvr_device *device)
|
||||
{
|
||||
struct pvr_device_static_clear_state *state = &device->static_clear_state;
|
||||
const struct pvr_device_info *dev_info = &device->pdevice->dev_info;
|
||||
const uint32_t cache_line_size = rogue_get_slc_cache_line_size(dev_info);
|
||||
const float vf_x_max = (float)rogue_get_param_vf_max_x(dev_info);
|
||||
const float vf_y_max = (float)rogue_get_param_vf_max_y(dev_info);
|
||||
const struct rogue_shader_binary *passthrough_vert_shader;
|
||||
struct pvr_pds_vertex_shader_program pds_program;
|
||||
VkResult result;
|
||||
|
||||
const float vertices[4][3] = { { 0.0f, 0.0f, 0.0f },
|
||||
{ vf_x_max, 0.0f, 0.0f },
|
||||
{ 0.0f, vf_y_max, 0.0f },
|
||||
{ vf_x_max, vf_y_max, 0.0f } };
|
||||
|
||||
static_assert(ARRAY_SIZE(vertices) == PVR_CLEAR_VERTEX_COUNT,
|
||||
"Size mismatch");
|
||||
static_assert(ARRAY_SIZE(vertices[0]) == PVR_CLEAR_VERTEX_COORDINATES,
|
||||
"Size mismatch");
|
||||
|
||||
if (PVR_HAS_FEATURE(dev_info, gs_rta_support)) {
|
||||
struct util_dynarray passthrough_rta_vert_shader;
|
||||
|
||||
util_dynarray_init(&passthrough_rta_vert_shader, NULL);
|
||||
pvr_hard_code_get_passthrough_rta_vertex_shader(
|
||||
dev_info,
|
||||
&passthrough_rta_vert_shader);
|
||||
|
||||
result = pvr_gpu_upload_usc(device,
|
||||
passthrough_rta_vert_shader.data,
|
||||
passthrough_rta_vert_shader.size,
|
||||
cache_line_size,
|
||||
&state->usc_multi_layer_vertex_shader_bo);
|
||||
if (result != VK_SUCCESS) {
|
||||
util_dynarray_fini(&passthrough_rta_vert_shader);
|
||||
return result;
|
||||
}
|
||||
|
||||
util_dynarray_fini(&passthrough_rta_vert_shader);
|
||||
} else {
|
||||
state->usc_multi_layer_vertex_shader_bo = NULL;
|
||||
}
|
||||
|
||||
pvr_hard_code_get_passthrough_vertex_shader(dev_info,
|
||||
&passthrough_vert_shader);
|
||||
|
||||
result = pvr_gpu_upload_usc(device,
|
||||
passthrough_vert_shader->data,
|
||||
passthrough_vert_shader->size,
|
||||
cache_line_size,
|
||||
&state->usc_vertex_shader_bo);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_free_usc_multi_layer_shader;
|
||||
|
||||
result = pvr_gpu_upload(device,
|
||||
device->heaps.general_heap,
|
||||
vertices,
|
||||
sizeof(vertices),
|
||||
sizeof(vertices[0][0]),
|
||||
&state->vertices_bo);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_free_usc_shader;
|
||||
|
||||
pvr_pds_clear_vertex_shader_program_init_base(&pds_program,
|
||||
state->usc_vertex_shader_bo);
|
||||
|
||||
result =
|
||||
pvr_pds_clear_vertex_shader_program_create_and_upload(&pds_program,
|
||||
device,
|
||||
state->vertices_bo,
|
||||
&state->pds);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_free_verices_buffer;
|
||||
|
||||
pvr_device_setup_graphics_static_clear_ppp_base(&state->ppp_base);
|
||||
pvr_device_setup_graphics_static_clear_ppp_templates(state->ppp_templates);
|
||||
|
||||
assert(pds_program.code_size <= state->pds.code_size);
|
||||
|
||||
/* TODO: The difference between the large and normal words is only the last
|
||||
* word. The value is 3 or 4 depending on the amount of indices. Should we
|
||||
* dedup this?
|
||||
*/
|
||||
|
||||
/* TODO: Figure out where the 4 * sizeof(uint32_t) comes from. */
|
||||
pvr_pack_clear_vdm_state(&device->pdevice->dev_info,
|
||||
&state->pds,
|
||||
pds_program.temps_used,
|
||||
3,
|
||||
4 * sizeof(uint32_t),
|
||||
1,
|
||||
state->vdm_words);
|
||||
|
||||
/* TODO: Figure out where the 4 * sizeof(uint32_t) comes from. */
|
||||
pvr_pack_clear_vdm_state(&device->pdevice->dev_info,
|
||||
&state->pds,
|
||||
pds_program.temps_used,
|
||||
4,
|
||||
4 * sizeof(uint32_t),
|
||||
1,
|
||||
state->large_clear_vdm_words);
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
err_free_verices_buffer:
|
||||
pvr_bo_free(device, state->vertices_bo);
|
||||
|
||||
err_free_usc_shader:
|
||||
pvr_bo_free(device, state->usc_vertex_shader_bo);
|
||||
|
||||
err_free_usc_multi_layer_shader:
|
||||
pvr_bo_free(device, state->usc_multi_layer_vertex_shader_bo);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void pvr_device_finish_graphics_static_clear_state(struct pvr_device *device)
|
||||
{
|
||||
struct pvr_device_static_clear_state *state = &device->static_clear_state;
|
||||
|
||||
pvr_bo_free(device, state->pds.pvr_bo);
|
||||
pvr_bo_free(device, state->vertices_bo);
|
||||
pvr_bo_free(device, state->usc_vertex_shader_bo);
|
||||
pvr_bo_free(device, state->usc_multi_layer_vertex_shader_bo);
|
||||
}
|
||||
|
||||
void pvr_pds_clear_vertex_shader_program_init_base(
|
||||
struct pvr_pds_vertex_shader_program *program,
|
||||
const struct pvr_bo *usc_shader_bo)
|
||||
|
|
|
|||
|
|
@ -24,10 +24,12 @@
|
|||
#ifndef PVR_CLEAR_H
|
||||
#define PVR_CLEAR_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include "pvr_csb.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
#define PVR_CLEAR_VERTEX_COUNT 4
|
||||
#define PVR_CLEAR_VERTEX_COORDINATES 3
|
||||
|
|
@ -42,6 +44,45 @@
|
|||
pvr_cmd_length(VDMCTRL_VDM_STATE5) + pvr_cmd_length(VDMCTRL_INDEX_LIST0) + \
|
||||
pvr_cmd_length(VDMCTRL_INDEX_LIST2) + pvr_cmd_length(VDMCTRL_INDEX_LIST3))
|
||||
|
||||
#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_cmd_buffer;
|
||||
struct pvr_device;
|
||||
|
|
@ -49,6 +90,50 @@ struct pvr_device_info;
|
|||
struct pvr_pds_upload;
|
||||
struct pvr_pds_vertex_shader_program;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
VkResult pvr_device_init_graphics_static_clear_state(struct pvr_device *device);
|
||||
void pvr_device_finish_graphics_static_clear_state(struct pvr_device *device);
|
||||
|
||||
VkResult pvr_emit_ppp_from_template(
|
||||
struct pvr_csb *const csb,
|
||||
const struct pvr_static_clear_ppp_template *const template,
|
||||
struct pvr_bo **const pvr_bo_out);
|
||||
|
||||
void pvr_pds_clear_vertex_shader_program_init_base(
|
||||
struct pvr_pds_vertex_shader_program *program,
|
||||
const struct pvr_bo *usc_shader_bo);
|
||||
|
|
|
|||
|
|
@ -1492,327 +1492,6 @@ 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
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Emit geom state from a configurable template.
|
||||
*
|
||||
* Note that the state is emitted by joining the template with a base so the
|
||||
* base must have been setup before calling this.
|
||||
*
|
||||
* \param[in] csb Control stream to emit to.
|
||||
* \param[in] template The configured template.
|
||||
* \param[out] pvr_bo_out Uploaded state's pvr_bo object.
|
||||
*
|
||||
* \return VK_SUCCESS if the state was successfully uploaded.
|
||||
*/
|
||||
VkResult pvr_emit_ppp_from_template(
|
||||
struct pvr_csb *const csb,
|
||||
const struct pvr_static_clear_ppp_template *const template,
|
||||
struct pvr_bo **const pvr_bo_out)
|
||||
{
|
||||
const uint32_t dword_count =
|
||||
pvr_cmd_length(TA_STATE_HEADER) + pvr_cmd_length(TA_STATE_ISPCTL) +
|
||||
pvr_cmd_length(TA_STATE_ISPA) + pvr_cmd_length(TA_STATE_ISPB) +
|
||||
(template->requires_pds_state ? PVR_STATIC_CLEAR_PDS_STATE_COUNT : 0) +
|
||||
pvr_cmd_length(TA_REGION_CLIP0) + pvr_cmd_length(TA_REGION_CLIP1) +
|
||||
pvr_cmd_length(TA_WCLAMP) + pvr_cmd_length(TA_OUTPUT_SEL) +
|
||||
pvr_cmd_length(TA_STATE_VARYING0) + pvr_cmd_length(TA_STATE_VARYING1) +
|
||||
pvr_cmd_length(TA_STATE_VARYING2) + pvr_cmd_length(TA_STATE_PPP_CTRL) +
|
||||
pvr_cmd_length(TA_STATE_STREAM_OUT0);
|
||||
|
||||
struct pvr_device *const device = csb->device;
|
||||
const uint32_t cache_line_size =
|
||||
rogue_get_slc_cache_line_size(&device->pdevice->dev_info);
|
||||
const struct pvr_static_clear_ppp_base *const base =
|
||||
&device->static_clear_state.ppp_base;
|
||||
struct pvr_bo *pvr_bo;
|
||||
uint32_t *stream;
|
||||
VkResult result;
|
||||
|
||||
result = pvr_bo_alloc(device,
|
||||
device->heaps.general_heap,
|
||||
dword_count * sizeof(uint32_t),
|
||||
cache_line_size,
|
||||
PVR_BO_ALLOC_FLAG_CPU_MAPPED,
|
||||
&pvr_bo);
|
||||
if (result != VK_SUCCESS) {
|
||||
*pvr_bo_out = NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
stream = (uint32_t *)pvr_bo->bo->map;
|
||||
|
||||
pvr_csb_write_value(stream, TA_STATE_HEADER, template->header);
|
||||
pvr_csb_write_struct(stream, TA_STATE_ISPCTL, &template->config.ispctl);
|
||||
pvr_csb_write_struct(stream, TA_STATE_ISPA, &template->config.ispa);
|
||||
pvr_csb_write_value(stream, TA_STATE_ISPB, template->ispb);
|
||||
|
||||
if (template->requires_pds_state) {
|
||||
static_assert(sizeof(*stream) == sizeof((*template->config.pds_state)[0]),
|
||||
"Size mismatch");
|
||||
for (uint32_t i = 0; i < PVR_STATIC_CLEAR_PDS_STATE_COUNT; i++)
|
||||
*stream++ = (*template->config.pds_state)[i];
|
||||
}
|
||||
|
||||
pvr_csb_write_struct(stream,
|
||||
TA_REGION_CLIP0,
|
||||
&template->config.region_clip0);
|
||||
pvr_csb_write_struct(stream,
|
||||
TA_REGION_CLIP1,
|
||||
&template->config.region_clip1);
|
||||
pvr_csb_write_value(stream, TA_WCLAMP, base->wclamp);
|
||||
pvr_csb_write_struct(stream, TA_OUTPUT_SEL, &template->config.output_sel);
|
||||
pvr_csb_write_value(stream, TA_STATE_VARYING0, base->varying_word[0]);
|
||||
pvr_csb_write_value(stream, TA_STATE_VARYING1, base->varying_word[1]);
|
||||
pvr_csb_write_value(stream, TA_STATE_VARYING2, base->varying_word[2]);
|
||||
pvr_csb_write_value(stream, TA_STATE_PPP_CTRL, base->ppp_ctrl);
|
||||
pvr_csb_write_value(stream, TA_STATE_STREAM_OUT0, base->stream_out0);
|
||||
|
||||
assert((uint64_t)(stream - (uint32_t *)pvr_bo->bo->map) == dword_count);
|
||||
|
||||
pvr_bo_cpu_unmap(device, pvr_bo);
|
||||
stream = NULL;
|
||||
|
||||
pvr_csb_emit (csb, VDMCTRL_PPP_STATE0, state) {
|
||||
state.word_count = dword_count;
|
||||
state.addrmsb = pvr_bo->vma->dev_addr;
|
||||
}
|
||||
|
||||
pvr_csb_emit (csb, VDMCTRL_PPP_STATE1, state) {
|
||||
state.addrlsb = pvr_bo->vma->dev_addr;
|
||||
}
|
||||
|
||||
*pvr_bo_out = pvr_bo;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
pvr_device_init_graphics_static_clear_state(struct pvr_device *device)
|
||||
{
|
||||
struct pvr_device_static_clear_state *state = &device->static_clear_state;
|
||||
const struct pvr_device_info *dev_info = &device->pdevice->dev_info;
|
||||
const uint32_t cache_line_size = rogue_get_slc_cache_line_size(dev_info);
|
||||
const float vf_x_max = (float)rogue_get_param_vf_max_x(dev_info);
|
||||
const float vf_y_max = (float)rogue_get_param_vf_max_y(dev_info);
|
||||
const struct rogue_shader_binary *passthrough_vert_shader;
|
||||
struct pvr_pds_vertex_shader_program pds_program;
|
||||
VkResult result;
|
||||
|
||||
const float vertices[4][3] = { { 0.0f, 0.0f, 0.0f },
|
||||
{ vf_x_max, 0.0f, 0.0f },
|
||||
{ 0.0f, vf_y_max, 0.0f },
|
||||
{ vf_x_max, vf_y_max, 0.0f } };
|
||||
|
||||
static_assert(ARRAY_SIZE(vertices) == PVR_CLEAR_VERTEX_COUNT,
|
||||
"Size mismatch");
|
||||
static_assert(ARRAY_SIZE(vertices[0]) == PVR_CLEAR_VERTEX_COORDINATES,
|
||||
"Size mismatch");
|
||||
|
||||
if (PVR_HAS_FEATURE(dev_info, gs_rta_support)) {
|
||||
struct util_dynarray passthrough_rta_vert_shader;
|
||||
|
||||
util_dynarray_init(&passthrough_rta_vert_shader, NULL);
|
||||
pvr_hard_code_get_passthrough_rta_vertex_shader(
|
||||
dev_info,
|
||||
&passthrough_rta_vert_shader);
|
||||
|
||||
result = pvr_gpu_upload_usc(device,
|
||||
passthrough_rta_vert_shader.data,
|
||||
passthrough_rta_vert_shader.size,
|
||||
cache_line_size,
|
||||
&state->usc_multi_layer_vertex_shader_bo);
|
||||
if (result != VK_SUCCESS) {
|
||||
util_dynarray_fini(&passthrough_rta_vert_shader);
|
||||
return result;
|
||||
}
|
||||
|
||||
util_dynarray_fini(&passthrough_rta_vert_shader);
|
||||
} else {
|
||||
state->usc_multi_layer_vertex_shader_bo = NULL;
|
||||
}
|
||||
|
||||
pvr_hard_code_get_passthrough_vertex_shader(dev_info,
|
||||
&passthrough_vert_shader);
|
||||
|
||||
result = pvr_gpu_upload_usc(device,
|
||||
passthrough_vert_shader->data,
|
||||
passthrough_vert_shader->size,
|
||||
cache_line_size,
|
||||
&state->usc_vertex_shader_bo);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_free_usc_multi_layer_shader;
|
||||
|
||||
result = pvr_gpu_upload(device,
|
||||
device->heaps.general_heap,
|
||||
vertices,
|
||||
sizeof(vertices),
|
||||
sizeof(vertices[0][0]),
|
||||
&state->vertices_bo);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_free_usc_shader;
|
||||
|
||||
pvr_pds_clear_vertex_shader_program_init_base(&pds_program,
|
||||
state->usc_vertex_shader_bo);
|
||||
|
||||
result =
|
||||
pvr_pds_clear_vertex_shader_program_create_and_upload(&pds_program,
|
||||
device,
|
||||
state->vertices_bo,
|
||||
&state->pds);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_free_verices_buffer;
|
||||
|
||||
pvr_device_setup_graphics_static_clear_ppp_base(&state->ppp_base);
|
||||
pvr_device_setup_graphics_static_clear_ppp_templates(state->ppp_templates);
|
||||
|
||||
assert(pds_program.code_size <= state->pds.code_size);
|
||||
|
||||
/* TODO: The difference between the large and normal words is only the last
|
||||
* word. The value is 3 or 4 depending on the amount of indices. Should we
|
||||
* dedup this?
|
||||
*/
|
||||
|
||||
/* TODO: Figure out where the 4 * sizeof(uint32_t) comes from. */
|
||||
pvr_pack_clear_vdm_state(&device->pdevice->dev_info,
|
||||
&state->pds,
|
||||
pds_program.temps_used,
|
||||
3,
|
||||
4 * sizeof(uint32_t),
|
||||
1,
|
||||
state->vdm_words);
|
||||
|
||||
/* TODO: Figure out where the 4 * sizeof(uint32_t) comes from. */
|
||||
pvr_pack_clear_vdm_state(&device->pdevice->dev_info,
|
||||
&state->pds,
|
||||
pds_program.temps_used,
|
||||
4,
|
||||
4 * sizeof(uint32_t),
|
||||
1,
|
||||
state->large_clear_vdm_words);
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
err_free_verices_buffer:
|
||||
pvr_bo_free(device, state->vertices_bo);
|
||||
|
||||
err_free_usc_shader:
|
||||
pvr_bo_free(device, state->usc_vertex_shader_bo);
|
||||
|
||||
err_free_usc_multi_layer_shader:
|
||||
pvr_bo_free(device, state->usc_multi_layer_vertex_shader_bo);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
pvr_device_finish_graphics_static_clear_state(struct pvr_device *device)
|
||||
{
|
||||
struct pvr_device_static_clear_state *state = &device->static_clear_state;
|
||||
|
||||
pvr_bo_free(device, state->pds.pvr_bo);
|
||||
pvr_bo_free(device, state->vertices_bo);
|
||||
pvr_bo_free(device, state->usc_vertex_shader_bo);
|
||||
pvr_bo_free(device, state->usc_multi_layer_vertex_shader_bo);
|
||||
}
|
||||
|
||||
/* FIXME: We should be calculating the size when we upload the code in
|
||||
* pvr_srv_setup_static_pixel_event_program().
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -171,45 +171,6 @@ enum pvr_stage_allocation {
|
|||
PVR_STAGE_ALLOCATION_COUNT
|
||||
};
|
||||
|
||||
#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)
|
||||
|
||||
enum pvr_event_state {
|
||||
PVR_EVENT_STATE_SET_BY_HOST,
|
||||
PVR_EVENT_STATE_RESET_BY_HOST,
|
||||
|
|
@ -308,42 +269,6 @@ 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_compute_query_shader {
|
||||
struct pvr_bo *usc_bo;
|
||||
|
||||
|
|
@ -1516,11 +1441,6 @@ void pvr_calculate_vertex_cam_size(const struct pvr_device_info *dev_info,
|
|||
uint32_t *const cam_size_out,
|
||||
uint32_t *const vs_max_instances_out);
|
||||
|
||||
VkResult pvr_emit_ppp_from_template(
|
||||
struct pvr_csb *const csb,
|
||||
const struct pvr_static_clear_ppp_template *const template,
|
||||
struct pvr_bo **const pvr_bo_out);
|
||||
|
||||
VkResult
|
||||
pvr_copy_or_resolve_color_image_region(struct pvr_cmd_buffer *cmd_buffer,
|
||||
const struct pvr_image *src,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue