pvr: Implement vkCreateSampler and vkDestroySampler APIs.

Implements vkCreateSampler and vkDestroySampler APIs.

Also fixes maxSamplerLodBias value from 15.0f to 16.0f
as it's the max supported by our hardware.

Also changing maxSamplerAnisotropy from 16.0f to 1.0f to
temporarily disable anisotropy as we are missing software
support for it.

Signed-off-by: Rajnesh Kanwal <rajnesh.kanwal@imgtec.com>
Reviewed-by: Frank Binns <frank.binns@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15557>
This commit is contained in:
Rajnesh Kanwal 2022-02-17 09:45:18 +00:00 committed by Marge Bot
parent b000abbe7f
commit eacf944e52
4 changed files with 167 additions and 13 deletions

View File

@ -55,6 +55,7 @@ const struct pvr_device_features pvr_device_features_4_V_2_51 = {
.has_robust_buffer_access = true,
.has_slc_cache_line_size_bits = true,
.has_slc_mcu_cache_controls = true,
.has_tf_bicubic_filter = true,
.has_tile_size_x = true,
.has_tile_size_y = true,
.has_tpu_array_textures = true,
@ -101,6 +102,7 @@ const struct pvr_device_quirks pvr_device_quirks_4_40_2_51 = {
.has_brn48492 = true,
.has_brn48545 = true,
.has_brn49032 = true,
.has_brn51025 = true,
.has_brn51210 = true,
.has_brn51764 = true,
.has_brn52354 = true,
@ -135,9 +137,9 @@ const struct pvr_device_features pvr_device_features_33_V_11_3 = {
.has_simple_internal_parameter_format_v2 = true,
.has_simple_parameter_format_version = true,
.has_slc_cache_line_size_bits = true,
.has_tile_size_16x16 = true,
.has_tile_size_x = true,
.has_tile_size_y = true,
.has_tile_size_16x16 = true,
.has_tpu_extended_integer_lookup = true,
.has_tpu_image_state_v2 = true,
.has_usc_f16sop_u8 = true,
@ -210,9 +212,9 @@ const struct pvr_device_features pvr_device_features_36_V_104_796 = {
.has_simple_internal_parameter_format_v2 = true,
.has_simple_parameter_format_version = true,
.has_slc_cache_line_size_bits = true,
.has_tile_size_16x16 = true,
.has_tile_size_x = true,
.has_tile_size_y = true,
.has_tile_size_16x16 = true,
.has_tpu_extended_integer_lookup = true,
.has_tpu_image_state_v2 = true,
.has_usc_f16sop_u8 = true,

View File

@ -275,9 +275,10 @@ struct pvr_device_features {
bool has_simple_parameter_format_version : 1;
bool has_slc_cache_line_size_bits : 1;
bool has_slc_mcu_cache_controls : 1;
bool has_tf_bicubic_filter : 1;
bool has_tile_size_16x16 : 1;
bool has_tile_size_x : 1;
bool has_tile_size_y : 1;
bool has_tile_size_16x16 : 1;
bool has_tpu_array_textures : 1;
bool has_tpu_extended_integer_lookup : 1;
bool has_tpu_image_state_v2 : 1;
@ -330,6 +331,7 @@ struct pvr_device_quirks {
bool has_brn48492 : 1;
bool has_brn48545 : 1;
bool has_brn49032 : 1;
bool has_brn51025 : 1;
bool has_brn51210 : 1;
bool has_brn51764 : 1;
bool has_brn52354 : 1;

View File

@ -55,6 +55,7 @@
#include "util/u_math.h"
#include "vk_alloc.h"
#include "vk_log.h"
#include "vk_object.h"
#include "vk_util.h"
#define PVR_GLOBAL_FREE_LIST_INITIAL_SIZE (2U * 1024U * 1024U)
@ -753,8 +754,8 @@ void pvr_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
.maxDrawIndexedIndexValue = UINT32_MAX,
.maxDrawIndirectCount = 2U * 1024U * 1024U * 1024U,
.maxSamplerLodBias = 15.0f,
.maxSamplerAnisotropy = 16.0f,
.maxSamplerLodBias = 16.0f,
.maxSamplerAnisotropy = 1.0f,
.maxViewports = PVR_MAX_VIEWPORTS,
.maxViewportDimensions[0] = max_render_size,
@ -1582,13 +1583,6 @@ void pvr_DestroyBuffer(VkDevice _device,
vk_object_free(&device->vk, pAllocator, buffer);
}
void pvr_DestroySampler(VkDevice _device,
VkSampler _sampler,
const VkAllocationCallbacks *pAllocator)
{
assert(!"Unimplemented");
}
VkResult pvr_gpu_upload(struct pvr_device *device,
struct pvr_winsys_heap *heap,
const void *data,
@ -1952,15 +1946,169 @@ vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t *pSupportedVersion)
return VK_SUCCESS;
}
static uint32_t
pvr_sampler_get_hw_filter_from_vk(const struct pvr_device_info *dev_info,
VkFilter filter)
{
switch (filter) {
case VK_FILTER_NEAREST:
return PVRX(TEXSTATE_FILTER_POINT);
case VK_FILTER_LINEAR:
return PVRX(TEXSTATE_FILTER_LINEAR);
default:
unreachable("Unknown filter type.");
}
}
static uint32_t
pvr_sampler_get_hw_addr_mode_from_vk(VkSamplerAddressMode addr_mode)
{
switch (addr_mode) {
case VK_SAMPLER_ADDRESS_MODE_REPEAT:
return PVRX(TEXSTATE_ADDRMODE_REPEAT);
case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
return PVRX(TEXSTATE_ADDRMODE_FLIP);
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
return PVRX(TEXSTATE_ADDRMODE_CLAMP_TO_EDGE);
case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
return PVRX(TEXSTATE_ADDRMODE_FLIP_ONCE_THEN_CLAMP);
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:
return PVRX(TEXSTATE_ADDRMODE_CLAMP_TO_BORDER);
default:
unreachable("Invalid sampler address mode.");
}
}
VkResult pvr_CreateSampler(VkDevice _device,
const VkSamplerCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkSampler *pSampler)
{
assert(!"Unimplemented");
PVR_FROM_HANDLE(pvr_device, device, _device);
struct pvr_sampler *sampler;
float lod_rounding_bias;
VkFilter min_filter;
VkFilter mag_filter;
float min_lod;
float max_lod;
sampler = vk_object_alloc(&device->vk,
pAllocator,
sizeof(*sampler),
VK_OBJECT_TYPE_SAMPLER);
if (!sampler)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
mag_filter = pCreateInfo->magFilter;
min_filter = pCreateInfo->minFilter;
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
* <= 0 implies magnification, while LOD > 0 implies minification.
*
* As a workaround, we override magFilter with minFilter if we know that
* the magnification filter will never be used due to clamping anyway
* (i.e. minLod > 0). Conversely, we override minFilter with magFilter
* if maxLod <= 0.
*/
if (pCreateInfo->minLod > 0.0f) {
/* The clamped LOD will always be positive => always minify. */
mag_filter = pCreateInfo->minFilter;
}
if (pCreateInfo->maxLod <= 0.0f) {
/* The clamped LOD will always be negative or zero => always
* magnify.
*/
min_filter = pCreateInfo->magFilter;
}
}
pvr_csb_pack (&sampler->sampler_word, TEXSTATE_SAMPLER, word) {
const struct pvr_device_info *dev_info = &device->pdevice->dev_info;
const float lod_clamp_max = (float)PVRX(TEXSTATE_CLAMP_MAX) /
(1 << PVRX(TEXSTATE_CLAMP_FRACTIONAL_BITS));
const float max_dadjust = ((float)(PVRX(TEXSTATE_DADJUST_MAX_UINT) -
PVRX(TEXSTATE_DADJUST_ZERO_UINT))) /
(1 << PVRX(TEXSTATE_DADJUST_FRACTIONAL_BITS));
const float min_dadjust = ((float)(PVRX(TEXSTATE_DADJUST_MIN_UINT) -
PVRX(TEXSTATE_DADJUST_ZERO_UINT))) /
(1 << PVRX(TEXSTATE_DADJUST_FRACTIONAL_BITS));
word.magfilter = pvr_sampler_get_hw_filter_from_vk(dev_info, mag_filter);
word.minfilter = pvr_sampler_get_hw_filter_from_vk(dev_info, min_filter);
if (pCreateInfo->mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR)
word.mipfilter = true;
word.addrmode_u =
pvr_sampler_get_hw_addr_mode_from_vk(pCreateInfo->addressModeU);
word.addrmode_v =
pvr_sampler_get_hw_addr_mode_from_vk(pCreateInfo->addressModeV);
word.addrmode_w =
pvr_sampler_get_hw_addr_mode_from_vk(pCreateInfo->addressModeW);
/* The Vulkan 1.0.205 spec says:
*
* The absolute value of mipLodBias must be less than or equal to
* VkPhysicalDeviceLimits::maxSamplerLodBias.
*/
word.dadjust =
PVRX(TEXSTATE_DADJUST_ZERO_UINT) +
util_signed_fixed(
CLAMP(pCreateInfo->mipLodBias, min_dadjust, max_dadjust),
PVRX(TEXSTATE_DADJUST_FRACTIONAL_BITS));
/* Anisotropy is not supported for now. */
word.anisoctl = PVRX(TEXSTATE_ANISOCTL_DISABLED);
if (PVR_HAS_QUIRK(&device->pdevice->dev_info, 51025) &&
pCreateInfo->mipmapMode == VK_SAMPLER_MIPMAP_MODE_NEAREST) {
/* When MIPMAP_MODE_NEAREST is enabled, the LOD level should be
* selected by adding 0.5 and then truncating the input LOD value.
* This hardware adds the 0.5 bias before clamping against
* lodmin/lodmax, while Vulkan specifies the bias to be added after
* clamping. We compensate for this difference by adding the 0.5
* bias to the LOD bounds, too.
*/
lod_rounding_bias = 0.5f;
} else {
lod_rounding_bias = 0.0f;
}
min_lod = pCreateInfo->minLod + lod_rounding_bias;
word.minlod = util_unsigned_fixed(CLAMP(min_lod, 0.0f, lod_clamp_max),
PVRX(TEXSTATE_CLAMP_FRACTIONAL_BITS));
max_lod = pCreateInfo->maxLod + lod_rounding_bias;
word.maxlod = util_unsigned_fixed(CLAMP(max_lod, 0.0f, lod_clamp_max),
PVRX(TEXSTATE_CLAMP_FRACTIONAL_BITS));
word.bordercolor_index = pCreateInfo->borderColor;
if (pCreateInfo->unnormalizedCoordinates)
word.non_normalized_coords = true;
}
*pSampler = pvr_sampler_to_handle(sampler);
return VK_SUCCESS;
}
void pvr_DestroySampler(VkDevice _device,
VkSampler _sampler,
const VkAllocationCallbacks *pAllocator)
{
PVR_FROM_HANDLE(pvr_device, device, _device);
PVR_FROM_HANDLE(pvr_sampler, sampler, _sampler);
if (!sampler)
return;
vk_object_free(&device->vk, pAllocator, sampler);
}
void pvr_GetBufferMemoryRequirements2(
VkDevice _device,
const VkBufferMemoryRequirementsInfo2 *pInfo,

View File

@ -356,6 +356,8 @@ struct pvr_image_view {
struct pvr_sampler {
struct vk_object_base base;
uint64_t sampler_word;
};
struct pvr_descriptor_size_info {