pvr: Add support for sampler border colors

Currently only the six vulkan 1.0 pre-defined formats are supported,
but some basic infrastructure that will be useful for implementing
VK_EXT_custom_border_color (and vulkan 1.1) is included.

Only formats currently listed in the pvr_format_table in pvr_formats.c
are currently supported. Unlike most (all?) other drivers, the PowerVR
hardware requires each entry in the border color table to be encoded
for every hardware format (of which there are 128 available, plus 128
for compressed formats).

Also in this commit:
 - Two new constants in rogue_texstate.xml:
    - IMAGE_WORD0_TEXFORMAT_MAX_SIZE, and
    - SAMPLER_BORDERCOLOR_INDEX_MAX_SIZE; and
 - A new device feature (tpu_border_colour_enhanced)

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/21555>
This commit is contained in:
Matt Coster
2023-02-24 14:06:39 +00:00
committed by Marge Bot
parent b8a32e7694
commit 4a2e62844b
12 changed files with 1278 additions and 21 deletions

View File

@@ -151,6 +151,7 @@ const struct pvr_device_features pvr_device_features_33_V_11_3 = {
.has_tile_size_16x16 = true,
.has_tile_size_x = true,
.has_tile_size_y = true,
.has_tpu_border_colour_enhanced = true,
.has_tpu_extended_integer_lookup = true,
.has_tpu_image_state_v2 = true,
.has_usc_f16sop_u8 = true,
@@ -235,6 +236,7 @@ const struct pvr_device_features pvr_device_features_36_V_104_796 = {
.has_tile_size_16x16 = true,
.has_tile_size_x = true,
.has_tile_size_y = true,
.has_tpu_border_colour_enhanced = true,
.has_tpu_extended_integer_lookup = true,
.has_tpu_image_state_v2 = true,
.has_usc_f16sop_u8 = true,

View File

@@ -286,6 +286,7 @@ struct pvr_device_features {
bool has_tile_size_x : 1;
bool has_tile_size_y : 1;
bool has_tpu_array_textures : 1;
bool has_tpu_border_colour_enhanced : 1;
bool has_tpu_extended_integer_lookup : 1;
bool has_tpu_image_state_v2 : 1;
bool has_usc_f16sop_u8 : 1;

View File

@@ -267,7 +267,9 @@ SOFTWARE.
<field name="width" start="34" end="47" type="uint">
<define name="MAX_SIZE" value="16383"/>
</field>
<field name="texformat" start="27" end="33" type="FORMAT"/>
<field name="texformat" start="27" end="33" type="FORMAT">
<define name="MAX_SIZE" value="127"/>
</field>
<field name="texformat_compressed" start="27" end="33" type="FORMAT_COMPRESSED"/>
<field name="minlod" start="17" end="26" type="uint"/>
<field name="swiz0" start="14" end="16" type="SWIZ"/>
@@ -325,7 +327,9 @@ SOFTWARE.
<field name="texaddr_plane2_lo" start="50" end="63" shift="2" type="address"/>
<field name="cmp_mode" start="59" end="61" type="CMP_MODE"/>
<field name="addrmode_w" start="56" end="58" type="ADDRMODE"/>
<field name="bordercolor_index" start="50" end="55" type="uint"/>
<field name="bordercolor_index" start="50" end="55" type="uint">
<define name="MAX_SIZE" value="63"/>
</field>
<field name="non_normalized_coords" start="49" end="49" type="bool"/>
<field name="lumakey_alphamult" start="48" end="48" type="bool"/>
<field name="lumakey" start="47" end="47" type="bool"/>

View File

@@ -39,6 +39,7 @@ pvr_files = files(
'winsys/pvr_winsys_helper.c',
'pvr_blit.c',
'pvr_bo.c',
'pvr_border.c',
'pvr_clear.c',
'pvr_cmd_buffer.c',
'pvr_csb.c',
@@ -111,7 +112,7 @@ endif
libvulkan_powervr_mesa = shared_library(
'vulkan_powervr_mesa',
[pvr_files, pvr_entrypoints],
[pvr_files, pvr_entrypoints, u_format_pack_h],
include_directories : [
pvr_includes,
inc_gallium_aux,

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,76 @@
/*
* Copyright © 2023 Imagination Technologies Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef PVR_BORDER_H
#define PVR_BORDER_H
#include <stdbool.h>
#include <stdint.h>
#include <vulkan/vulkan_core.h>
#include "pvr_csb.h"
#include "util/bitset.h"
#define PVR_BORDER_COLOR_TABLE_NR_ENTRIES \
(PVRX(TEXSTATE_SAMPLER_BORDERCOLOR_INDEX_MAX_SIZE) + 1)
#define PVR_BORDER_COLOR_TABLE_NR_BUILTIN_ENTRIES \
(VK_BORDER_COLOR_INT_OPAQUE_WHITE + 1U)
#define PVR_BORDER_COLOR_TABLE_NR_CUSTOM_ENTRIES \
(PVR_BORDER_COLOR_TABLE_NR_ENTRIES - \
PVR_BORDER_COLOR_TABLE_NR_BUILTIN_ENTRIES)
/* Forward declaration from "pvr_bo.h" */
struct pvr_bo;
/* Forward declaration from "pvr_private.h" */
struct pvr_device;
struct pvr_border_color_table {
BITSET_DECLARE(unused_entries, PVR_BORDER_COLOR_TABLE_NR_ENTRIES);
/* Contains an array of:
* PVR_BORDER_COLOR_TABLE_NR_ENTRIES x struct pvr_border_color_table_entry
*/
struct pvr_bo *table;
};
VkResult pvr_border_color_table_init(struct pvr_border_color_table *table,
struct pvr_device *device);
void pvr_border_color_table_finish(struct pvr_border_color_table *table,
struct pvr_device *device);
VkResult pvr_border_color_table_get_or_create_entry(
struct pvr_border_color_table *table,
const struct VkSamplerCreateInfo *sampler_create_info,
uint32_t *index_out);
static inline bool pvr_border_color_table_is_index_valid(
const struct pvr_border_color_table *const table,
const uint32_t index)
{
return !BITSET_TEST(table->unused_entries, index);
}
#endif /* PVR_BORDER_H */

View File

@@ -1436,11 +1436,6 @@ static VkResult pvr_sub_cmd_gfx_job_init(const struct pvr_device_info *dev_info,
job->ctrl_stream_addr = pvr_csb_get_start_address(&sub_cmd->control_stream);
/* FIXME: Need to set up the border color table at device creation
* time. Set to invalid for the time being.
*/
job->border_colour_table_addr = PVR_DEV_ADDR_INVALID;
if (sub_cmd->depth_bias_bo)
job->depth_bias_table_addr = sub_cmd->depth_bias_bo->dev_addr;
else

View File

@@ -41,6 +41,7 @@
#include "hwdef/rogue_hw_utils.h"
#include "pipe/p_defines.h"
#include "pvr_bo.h"
#include "pvr_border.h"
#include "pvr_clear.h"
#include "pvr_csb.h"
#include "pvr_csb_enum_helpers.h"
@@ -1876,6 +1877,10 @@ VkResult pvr_CreateDevice(VkPhysicalDevice physicalDevice,
if (result != VK_SUCCESS)
goto err_pvr_spm_finish_scratch_buffer_store;
result = pvr_border_color_table_init(&device->border_color_table, device);
if (result != VK_SUCCESS)
goto err_pvr_robustness_buffer_finish;
/* FIXME: Move this to a later stage and possibly somewhere other than
* pvr_device. The purpose of this is so that we don't have to get the size
* on each kick.
@@ -1891,6 +1896,9 @@ VkResult pvr_CreateDevice(VkPhysicalDevice physicalDevice,
return VK_SUCCESS;
err_pvr_robustness_buffer_finish:
pvr_robustness_buffer_finish(device);
err_pvr_spm_finish_scratch_buffer_store:
pvr_spm_finish_scratch_buffer_store(device);
@@ -1954,6 +1962,7 @@ void pvr_DestroyDevice(VkDevice _device,
if (!device)
return;
pvr_border_color_table_finish(&device->border_color_table, device);
pvr_robustness_buffer_finish(device);
pvr_spm_finish_scratch_buffer_store(device);
pvr_queues_destroy(device);
@@ -2987,10 +2996,12 @@ VkResult pvr_CreateSampler(VkDevice _device,
VkSampler *pSampler)
{
PVR_FROM_HANDLE(pvr_device, device, _device);
uint32_t border_color_table_index;
struct pvr_sampler *sampler;
float lod_rounding_bias;
VkFilter min_filter;
VkFilter mag_filter;
VkResult result;
float min_lod;
float max_lod;
@@ -3001,12 +3012,21 @@ VkResult pvr_CreateSampler(VkDevice _device,
pAllocator,
sizeof(*sampler),
VK_OBJECT_TYPE_SAMPLER);
if (!sampler)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
if (!sampler) {
result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
goto err_out;
}
mag_filter = pCreateInfo->magFilter;
min_filter = pCreateInfo->minFilter;
result =
pvr_border_color_table_get_or_create_entry(&device->border_color_table,
pCreateInfo,
&border_color_table_index);
if (result != VK_SUCCESS)
goto err_free_sampler;
if (PVR_HAS_QUIRK(&device->pdevice->dev_info, 51025)) {
/* The min/mag filters may need adjustment here, the GPU should decide
* which of the two filters to use based on the clamped LOD value: LOD
@@ -3108,7 +3128,7 @@ VkResult pvr_CreateSampler(VkDevice _device,
word.maxlod = util_unsigned_fixed(CLAMP(max_lod, 0.0f, lod_clamp_max),
PVRX(TEXSTATE_CLAMP_FRACTIONAL_BITS));
word.bordercolor_index = pCreateInfo->borderColor;
word.bordercolor_index = border_color_table_index;
if (pCreateInfo->unnormalizedCoordinates)
word.non_normalized_coords = true;
@@ -3117,6 +3137,12 @@ VkResult pvr_CreateSampler(VkDevice _device,
*pSampler = pvr_sampler_to_handle(sampler);
return VK_SUCCESS;
err_free_sampler:
vk_object_free(&device->vk, pAllocator, sampler);
err_out:
return result;
}
void pvr_DestroySampler(VkDevice _device,

View File

@@ -41,7 +41,8 @@ pvr_submit_info_stream_init(struct pvr_compute_ctx *ctx,
struct pvr_sub_cmd_compute *sub_cmd,
struct pvr_winsys_compute_submit_info *submit_info)
{
const struct pvr_physical_device *const pdevice = ctx->device->pdevice;
const struct pvr_device *const device = ctx->device;
const struct pvr_physical_device *const pdevice = device->pdevice;
const struct pvr_device_runtime_info *const dev_runtime_info =
&pdevice->dev_runtime_info;
const struct pvr_device_info *const dev_info = &pdevice->dev_info;
@@ -49,13 +50,11 @@ pvr_submit_info_stream_init(struct pvr_compute_ctx *ctx,
uint32_t *stream_ptr = (uint32_t *)submit_info->fw_stream;
/* FIXME: Need to set up the border color table at device creation time. Set
* to invalid for the time being.
*/
pvr_csb_pack ((uint64_t *)stream_ptr,
CR_TPU_BORDER_COLOUR_TABLE_CDM,
value) {
value.border_colour_table_address = PVR_DEV_ADDR_INVALID;
value.border_colour_table_address =
device->border_color_table.table->vma->dev_addr;
}
stream_ptr += pvr_cmd_length(CR_TPU_BORDER_COLOUR_TABLE_CDM);

View File

@@ -938,7 +938,8 @@ static void pvr_geom_state_stream_init(struct pvr_render_ctx *ctx,
struct pvr_render_job *job,
struct pvr_winsys_geometry_state *state)
{
const struct pvr_device_info *dev_info = &ctx->device->pdevice->dev_info;
const struct pvr_device *const device = ctx->device;
const struct pvr_device_info *const dev_info = &device->pdevice->dev_info;
uint32_t *stream_ptr = (uint32_t *)state->fw_stream;
@@ -950,7 +951,8 @@ static void pvr_geom_state_stream_init(struct pvr_render_ctx *ctx,
pvr_csb_pack ((uint64_t *)stream_ptr,
CR_TPU_BORDER_COLOUR_TABLE_VDM,
value) {
value.border_colour_table_address = job->border_colour_table_addr;
value.border_colour_table_address =
device->border_color_table.table->vma->dev_addr;
}
stream_ptr += pvr_cmd_length(CR_TPU_BORDER_COLOUR_TABLE_VDM);
@@ -1058,7 +1060,8 @@ static void pvr_frag_state_stream_init(struct pvr_render_ctx *ctx,
struct pvr_render_job *job,
struct pvr_winsys_fragment_state *state)
{
const struct pvr_physical_device *const pdevice = ctx->device->pdevice;
const struct pvr_device *const device = ctx->device;
const struct pvr_physical_device *const pdevice = device->pdevice;
const struct pvr_device_runtime_info *dev_runtime_info =
&pdevice->dev_runtime_info;
const struct pvr_device_info *dev_info = &pdevice->dev_info;
@@ -1203,7 +1206,8 @@ static void pvr_frag_state_stream_init(struct pvr_render_ctx *ctx,
pvr_csb_pack ((uint64_t *)stream_ptr,
CR_TPU_BORDER_COLOUR_TABLE_PDM,
value) {
value.border_colour_table_address = job->border_colour_table_addr;
value.border_colour_table_address =
device->border_color_table.table->vma->dev_addr;
}
stream_ptr += pvr_cmd_length(CR_TPU_BORDER_COLOUR_TABLE_PDM);

View File

@@ -88,7 +88,6 @@ struct pvr_render_job {
pvr_dev_addr_t ctrl_stream_addr;
pvr_dev_addr_t border_colour_table_addr;
pvr_dev_addr_t depth_bias_table_addr;
pvr_dev_addr_t scissor_table_addr;

View File

@@ -38,6 +38,7 @@
#include "compiler/shader_enums.h"
#include "hwdef/rogue_hw_defs.h"
#include "pvr_border.h"
#include "pvr_clear.h"
#include "pvr_common.h"
#include "pvr_csb.h"
@@ -277,6 +278,8 @@ struct pvr_device {
struct pvr_bo *robustness_buffer;
struct vk_sync *presignaled_sync;
struct pvr_border_color_table border_color_table;
};
struct pvr_device_memory {