mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-06 06:40:08 +01:00
pvr: Add stencil support in render job setup
The implementation here assumes separate depth and stencil attachments are not possible, as they are in Vulkan without VK_KHR_dynamic_rendering and before core 1.3. Signed-off-by: Matt Coster <matt.coster@imgtec.com> Reviewed-by: Karmjit Mahil <Karmjit.Mahil@imgtec.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20160>
This commit is contained in:
parent
ff928d9567
commit
6404eee627
3 changed files with 108 additions and 95 deletions
|
|
@ -910,6 +910,11 @@ static VkResult pvr_sub_cmd_gfx_job_init(const struct pvr_device_info *dev_info,
|
|||
struct pvr_cmd_buffer *cmd_buffer,
|
||||
struct pvr_sub_cmd_gfx *sub_cmd)
|
||||
{
|
||||
static const VkClearDepthStencilValue default_ds_clear_value = {
|
||||
.depth = 1.0f,
|
||||
.stencil = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
const struct vk_dynamic_graphics_state *dynamic_state =
|
||||
&cmd_buffer->vk.dynamic_graphics_state;
|
||||
struct pvr_render_pass_info *render_pass_info =
|
||||
|
|
@ -1028,64 +1033,44 @@ static VkResult pvr_sub_cmd_gfx_job_init(const struct pvr_device_info *dev_info,
|
|||
render_pass_info->attachments[hw_render->ds_attach_idx];
|
||||
const struct pvr_image *image = vk_to_pvr_image(iview->vk.image);
|
||||
|
||||
if (vk_format_has_depth(image->vk.format)) {
|
||||
job->has_depth_attachment = vk_format_has_depth(image->vk.format);
|
||||
job->has_stencil_attachment = vk_format_has_stencil(image->vk.format);
|
||||
|
||||
if (job->has_depth_attachment || job->has_stencil_attachment) {
|
||||
uint32_t level_pitch =
|
||||
image->mip_levels[iview->vk.base_mip_level].pitch;
|
||||
|
||||
/* FIXME: Is this sufficient for depth buffers? */
|
||||
job->depth_addr = image->dev_addr;
|
||||
job->ds.addr = image->dev_addr;
|
||||
|
||||
job->depth_stride =
|
||||
pvr_stride_from_pitch(level_pitch, iview->vk.format);
|
||||
job->depth_height = iview->vk.extent.height;
|
||||
job->depth_physical_width =
|
||||
job->ds.stride = pvr_stride_from_pitch(level_pitch, iview->vk.format);
|
||||
job->ds.height = iview->vk.extent.height;
|
||||
job->ds.physical_width =
|
||||
u_minify(image->physical_extent.width, iview->vk.base_mip_level);
|
||||
job->depth_physical_height =
|
||||
job->ds.physical_height =
|
||||
u_minify(image->physical_extent.height, iview->vk.base_mip_level);
|
||||
job->depth_layer_size = image->layer_size;
|
||||
job->ds.layer_size = image->layer_size;
|
||||
|
||||
job->ds_clear_value = default_ds_clear_value;
|
||||
|
||||
if (hw_render->ds_attach_idx < render_pass_info->clear_value_count) {
|
||||
VkClearValue *clear_values =
|
||||
&render_pass_info->clear_values[hw_render->ds_attach_idx];
|
||||
const VkClearDepthStencilValue *const clear_values =
|
||||
&render_pass_info->clear_values[hw_render->ds_attach_idx]
|
||||
.depthStencil;
|
||||
|
||||
job->depth_clear_value = clear_values->depthStencil.depth;
|
||||
} else {
|
||||
job->depth_clear_value = 1.0f;
|
||||
if (job->has_depth_attachment)
|
||||
job->ds_clear_value.depth = clear_values->depth;
|
||||
|
||||
if (job->has_stencil_attachment)
|
||||
job->ds_clear_value.stencil = clear_values->stencil;
|
||||
}
|
||||
|
||||
job->depth_vk_format = iview->vk.format;
|
||||
|
||||
job->depth_memlayout = image->memlayout;
|
||||
} else {
|
||||
job->depth_addr = PVR_DEV_ADDR_INVALID;
|
||||
job->depth_stride = 0;
|
||||
job->depth_height = 0;
|
||||
job->depth_physical_width = 0;
|
||||
job->depth_physical_height = 0;
|
||||
job->depth_layer_size = 0;
|
||||
job->depth_clear_value = 1.0f;
|
||||
job->depth_vk_format = VK_FORMAT_UNDEFINED;
|
||||
job->depth_memlayout = PVR_MEMLAYOUT_LINEAR;
|
||||
}
|
||||
|
||||
if (vk_format_has_stencil(image->vk.format)) {
|
||||
/* FIXME: Is this sufficient for stencil buffers? */
|
||||
job->stencil_addr = image->dev_addr;
|
||||
} else {
|
||||
job->stencil_addr = PVR_DEV_ADDR_INVALID;
|
||||
job->ds.vk_format = iview->vk.format;
|
||||
job->ds.memlayout = image->memlayout;
|
||||
}
|
||||
} else {
|
||||
job->depth_addr = PVR_DEV_ADDR_INVALID;
|
||||
job->depth_stride = 0;
|
||||
job->depth_height = 0;
|
||||
job->depth_physical_width = 0;
|
||||
job->depth_physical_height = 0;
|
||||
job->depth_layer_size = 0;
|
||||
job->depth_clear_value = 1.0f;
|
||||
job->depth_vk_format = VK_FORMAT_UNDEFINED;
|
||||
job->depth_memlayout = PVR_MEMLAYOUT_LINEAR;
|
||||
|
||||
job->stencil_addr = PVR_DEV_ADDR_INVALID;
|
||||
job->has_depth_attachment = false;
|
||||
job->has_stencil_attachment = false;
|
||||
job->ds_clear_value = default_ds_clear_value;
|
||||
}
|
||||
|
||||
if (hw_render->ds_attach_idx != VK_ATTACHMENT_UNUSED) {
|
||||
|
|
|
|||
|
|
@ -1372,48 +1372,56 @@ static void pvr_frag_state_stream_init(struct pvr_render_ctx *ctx,
|
|||
}
|
||||
stream_ptr += pvr_cmd_length(CR_ISP_OCLQRY_BASE);
|
||||
|
||||
/* FIXME: Some additional set up needed to support depth and stencil
|
||||
* load/store operations.
|
||||
/* FIXME: Some additional set up needed to support depth/stencil load/store
|
||||
* operations.
|
||||
*/
|
||||
pvr_csb_pack ((uint64_t *)stream_ptr, CR_ISP_ZLSCTL, value) {
|
||||
uint32_t aligned_width =
|
||||
ALIGN_POT(job->depth_physical_width, ROGUE_IPF_TILE_SIZE_PIXELS);
|
||||
uint32_t aligned_height =
|
||||
ALIGN_POT(job->depth_physical_height, ROGUE_IPF_TILE_SIZE_PIXELS);
|
||||
if (job->has_depth_attachment) {
|
||||
uint32_t aligned_width =
|
||||
ALIGN_POT(job->ds.physical_width, ROGUE_IPF_TILE_SIZE_PIXELS);
|
||||
uint32_t aligned_height =
|
||||
ALIGN_POT(job->ds.physical_height, ROGUE_IPF_TILE_SIZE_PIXELS);
|
||||
|
||||
pvr_get_isp_num_tiles_xy(dev_info,
|
||||
job->samples,
|
||||
aligned_width,
|
||||
aligned_height,
|
||||
&value.zlsextent_x_z,
|
||||
&value.zlsextent_y_z);
|
||||
value.zlsextent_x_z -= 1;
|
||||
value.zlsextent_y_z -= 1;
|
||||
pvr_get_isp_num_tiles_xy(dev_info,
|
||||
job->samples,
|
||||
aligned_width,
|
||||
aligned_height,
|
||||
&value.zlsextent_x_z,
|
||||
&value.zlsextent_y_z);
|
||||
value.zlsextent_x_z -= 1;
|
||||
value.zlsextent_y_z -= 1;
|
||||
|
||||
if (job->depth_memlayout == PVR_MEMLAYOUT_TWIDDLED) {
|
||||
value.loadtwiddled = true;
|
||||
value.storetwiddled = true;
|
||||
}
|
||||
if (job->ds.memlayout == PVR_MEMLAYOUT_TWIDDLED) {
|
||||
value.loadtwiddled = true;
|
||||
value.storetwiddled = true;
|
||||
}
|
||||
|
||||
/* FIXME: This is suitable for the single depth format the driver
|
||||
* currently supports, but may need updating to handle other depth
|
||||
* formats.
|
||||
*/
|
||||
assert(job->depth_vk_format == VK_FORMAT_D32_SFLOAT);
|
||||
assert(job->ds.vk_format == VK_FORMAT_D32_SFLOAT);
|
||||
value.zloadformat = PVRX(CR_ZLOADFORMAT_TYPE_F32Z);
|
||||
value.zstoreformat = PVRX(CR_ZSTOREFORMAT_TYPE_F32Z);
|
||||
}
|
||||
stream_ptr += pvr_cmd_length(CR_ISP_ZLSCTL);
|
||||
|
||||
pvr_csb_pack ((uint64_t *)stream_ptr, CR_ISP_ZLOAD_BASE, value) {
|
||||
value.addr = job->depth_addr;
|
||||
if (job->has_depth_attachment)
|
||||
value.addr = job->ds.addr;
|
||||
}
|
||||
stream_ptr += pvr_cmd_length(CR_ISP_ZLOAD_BASE);
|
||||
|
||||
pvr_csb_pack ((uint64_t *)stream_ptr, CR_ISP_STENCIL_LOAD_BASE, value) {
|
||||
value.addr = job->stencil_addr;
|
||||
if (job->has_stencil_attachment) {
|
||||
value.addr = job->ds.addr;
|
||||
|
||||
/* FIXME: May need to set value.enable to true. */
|
||||
/* This should be set iff we only have a stencil attachment; all
|
||||
* currently supported formats with a stencil component also contain
|
||||
* depth.
|
||||
*/
|
||||
value.enable = false;
|
||||
}
|
||||
}
|
||||
stream_ptr += pvr_cmd_length(CR_ISP_STENCIL_LOAD_BASE);
|
||||
|
||||
|
|
@ -1456,7 +1464,7 @@ static void pvr_frag_state_stream_init(struct pvr_render_ctx *ctx,
|
|||
* currently supports, but may need updating to handle other depth
|
||||
* formats.
|
||||
*/
|
||||
value.value = fui(job->depth_clear_value);
|
||||
value.value = fui(job->ds_clear_value.depth);
|
||||
}
|
||||
stream_ptr += pvr_cmd_length(CR_ISP_BGOBJDEPTH);
|
||||
|
||||
|
|
@ -1465,10 +1473,12 @@ static void pvr_frag_state_stream_init(struct pvr_render_ctx *ctx,
|
|||
|
||||
value.mask = true;
|
||||
|
||||
/* FIXME: Hard code this for now as we don't currently support any
|
||||
* stencil image formats.
|
||||
*/
|
||||
value.stencil = 0xFF;
|
||||
if (job->has_stencil_attachment &&
|
||||
job->ds.vk_format != VK_FORMAT_D24_UNORM_S8_UINT) {
|
||||
unreachable("Unsupported stencil format");
|
||||
}
|
||||
|
||||
value.stencil = job->ds_clear_value.stencil & 0xFF;
|
||||
}
|
||||
stream_ptr += pvr_cmd_length(CR_ISP_BGOBJVALS);
|
||||
|
||||
|
|
@ -1484,6 +1494,14 @@ static void pvr_frag_state_stream_init(struct pvr_render_ctx *ctx,
|
|||
* is just one of them.
|
||||
*/
|
||||
value.process_empty_tiles = job->process_empty_tiles;
|
||||
|
||||
/* For integer depth formats we'll convert the specified floating point
|
||||
* depth bias values and specify them as integers. In this mode a depth
|
||||
* bias factor of 1.0 equates to 1 ULP of increase to the depth value.
|
||||
*/
|
||||
value.dbias_is_int = PVR_HAS_ERN(dev_info, 42307) &&
|
||||
(job->ds.vk_format == VK_FORMAT_D16_UNORM ||
|
||||
job->ds.vk_format == VK_FORMAT_D24_UNORM_S8_UINT);
|
||||
}
|
||||
/* FIXME: When pvr_setup_tiles_in_flight() is refactored it might be
|
||||
* possible to fully pack CR_ISP_CTL above rather than having to OR in part
|
||||
|
|
@ -1540,18 +1558,20 @@ static void pvr_frag_state_stream_init(struct pvr_render_ctx *ctx,
|
|||
|
||||
if (PVR_HAS_FEATURE(dev_info, zls_subtile)) {
|
||||
pvr_csb_pack (stream_ptr, CR_ISP_ZLS_PIXELS, value) {
|
||||
value.x = job->depth_stride - 1;
|
||||
value.y = job->depth_height - 1;
|
||||
if (job->has_depth_attachment) {
|
||||
value.x = job->ds.stride - 1;
|
||||
value.y = job->ds.height - 1;
|
||||
}
|
||||
}
|
||||
stream_ptr += pvr_cmd_length(CR_ISP_ZLS_PIXELS);
|
||||
}
|
||||
|
||||
/* zls_stride */
|
||||
*stream_ptr = job->depth_layer_size;
|
||||
*stream_ptr = job->has_depth_attachment ? job->ds.layer_size : 0;
|
||||
stream_ptr++;
|
||||
|
||||
/* sls_stride */
|
||||
*stream_ptr = job->depth_layer_size;
|
||||
*stream_ptr = job->has_stencil_attachment ? job->ds.layer_size : 0;
|
||||
stream_ptr++;
|
||||
|
||||
if (PVR_HAS_FEATURE(dev_info, gpu_multicore_support)) {
|
||||
|
|
@ -1612,10 +1632,10 @@ pvr_render_job_ws_fragment_state_init(struct pvr_render_ctx *ctx,
|
|||
/* FIXME: move to its own function? */
|
||||
state->flags = 0;
|
||||
|
||||
if (job->depth_addr.addr)
|
||||
if (job->has_depth_attachment)
|
||||
state->flags |= PVR_WINSYS_FRAG_FLAG_DEPTH_BUFFER_PRESENT;
|
||||
|
||||
if (job->stencil_addr.addr)
|
||||
if (job->has_stencil_attachment)
|
||||
state->flags |= PVR_WINSYS_FRAG_FLAG_STENCIL_BUFFER_PRESENT;
|
||||
|
||||
if (job->disable_compute_overlap)
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ struct pvr_render_job {
|
|||
bool enable_bg_tag;
|
||||
bool process_empty_tiles;
|
||||
bool get_vis_results;
|
||||
bool has_depth_attachment;
|
||||
bool has_stencil_attachment;
|
||||
|
||||
uint32_t pds_pixel_event_data_offset;
|
||||
|
||||
|
|
@ -61,25 +63,31 @@ struct pvr_render_job {
|
|||
pvr_dev_addr_t depth_bias_table_addr;
|
||||
pvr_dev_addr_t scissor_table_addr;
|
||||
|
||||
pvr_dev_addr_t depth_addr;
|
||||
uint32_t depth_stride;
|
||||
uint32_t depth_height;
|
||||
uint32_t depth_physical_width;
|
||||
uint32_t depth_physical_height;
|
||||
uint32_t depth_layer_size;
|
||||
float depth_clear_value;
|
||||
VkFormat depth_vk_format;
|
||||
/* FIXME: This should be of type 'enum pvr_memlayout', but this is defined
|
||||
* in pvr_private.h, which causes a circular include dependency. For now,
|
||||
* treat it has a uint32_t. A couple of ways to possibly fix this:
|
||||
*
|
||||
* 1. Merge the contents of this header file into pvr_private.h.
|
||||
* 2. Move 'enum pvr_memlayout' into it a new header that can be included
|
||||
* by both this header and pvr_private.h.
|
||||
/* Unless VK_KHR_dynamic_rendering or core 1.3 is supported, Vulkan does not
|
||||
* allow for separate depth and stencil attachments. We don't bother storing
|
||||
* separate parameters for them here (yet). If both has_depth_attachment and
|
||||
* has_stencil_attachment are false, the contents are undefined.
|
||||
*/
|
||||
uint32_t depth_memlayout;
|
||||
struct pvr_ds_attachment {
|
||||
pvr_dev_addr_t addr;
|
||||
uint32_t stride;
|
||||
uint32_t height;
|
||||
uint32_t physical_width;
|
||||
uint32_t physical_height;
|
||||
uint32_t layer_size;
|
||||
VkFormat vk_format;
|
||||
/* FIXME: This should be of type 'enum pvr_memlayout', but this is defined
|
||||
* in pvr_private.h, which causes a circular include dependency. For now,
|
||||
* treat it as a uint32_t. A couple of ways to possibly fix this:
|
||||
*
|
||||
* 1. Merge the contents of this header file into pvr_private.h.
|
||||
* 2. Move 'enum pvr_memlayout' into it a new header that can be
|
||||
* included by both this header and pvr_private.h.
|
||||
*/
|
||||
uint32_t memlayout;
|
||||
} ds;
|
||||
|
||||
pvr_dev_addr_t stencil_addr;
|
||||
VkClearDepthStencilValue ds_clear_value;
|
||||
|
||||
uint32_t samples;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue