mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-22 17:28:09 +02:00
This is achieved by the following steps: #ifndef DEBUG => #if !MESA_DEBUG defined(DEBUG) => MESA_DEBUG #ifdef DEBUG => #if MESA_DEBUG This is done by replace in vscode excludes docs,*.rs,addrlib,src/imgui,*.sh,src/intel/vulkan/grl/gpu These are safe because those files should keep DEBUG macro is already excluded; and not directly replace DEBUG, as we have some symbols around it. Use debug or NDEBUG instead of DEBUG in comments when proper This for reduce the usage of DEBUG, so it's easier migrating to MESA_DEBUG These are found when migrating DEBUG to MESA_DEBUG, these are all comment update, so it's safe Replace comment /* DEBUG */ and /* !DEBUG */ with proper /* MESA_DEBUG */ or /* !MESA_DEBUG */ manually DEBUG || !NDEBUG -> MESA_DEBUG || !NDEBUG !DEBUG && NDEBUG -> !(MESA_DEBUG || !NDEBUG) Replace the DEBUG present in comment with proper new MESA_DEBUG manually Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> Acked-by: David Heidelberg <david.heidelberg@collabora.com> Reviewed-by: Eric Engestrom <eric@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28092>
238 lines
8 KiB
C
238 lines
8 KiB
C
/*
|
|
* 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.
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <vulkan/vulkan_core.h>
|
|
|
|
#include "hwdef/rogue_hw_utils.h"
|
|
#include "pvr_bo.h"
|
|
#include "pvr_border.h"
|
|
#include "pvr_device_info.h"
|
|
#include "pvr_formats.h"
|
|
#include "pvr_private.h"
|
|
#include "util/bitset.h"
|
|
#include "util/format/u_format.h"
|
|
#include "util/format/u_formats.h"
|
|
#include "util/log.h"
|
|
#include "util/macros.h"
|
|
#include "vk_format.h"
|
|
#include "vk_log.h"
|
|
#include "vk_sampler.h"
|
|
|
|
struct pvr_border_color_table_value {
|
|
uint8_t value[16];
|
|
} PACKED;
|
|
static_assert(sizeof(struct pvr_border_color_table_value) ==
|
|
4 * sizeof(uint32_t),
|
|
"struct pvr_border_color_table_value must be 4 x u32");
|
|
|
|
struct pvr_border_color_table_entry {
|
|
struct pvr_border_color_table_value values[PVR_TEX_FORMAT_COUNT * 2];
|
|
} PACKED;
|
|
|
|
static inline void pvr_border_color_table_pack_single(
|
|
struct pvr_border_color_table_value *const dst,
|
|
const union pipe_color_union *const color,
|
|
const struct pvr_tex_format_description *const format,
|
|
const bool is_int)
|
|
{
|
|
const enum pipe_format pipe_format = is_int ? format->pipe_format_int
|
|
: format->pipe_format_float;
|
|
|
|
if (pipe_format == PIPE_FORMAT_NONE)
|
|
return;
|
|
|
|
memset(dst->value, 0, sizeof(dst->value));
|
|
|
|
if (util_format_is_depth_or_stencil(pipe_format)) {
|
|
if (is_int) {
|
|
const uint8_t s_color[4] = {
|
|
color->ui[0],
|
|
color->ui[1],
|
|
color->ui[2],
|
|
color->ui[3],
|
|
};
|
|
|
|
util_format_pack_s_8uint(pipe_format, dst->value, s_color, 1);
|
|
} else {
|
|
util_format_pack_z_float(pipe_format, dst->value, color->f, 1);
|
|
}
|
|
} else {
|
|
util_format_pack_rgba(pipe_format, dst->value, color, 1);
|
|
}
|
|
}
|
|
|
|
static inline void pvr_border_color_table_pack_single_compressed(
|
|
struct pvr_border_color_table_value *const dst,
|
|
const union pipe_color_union *const color,
|
|
const struct pvr_tex_format_compressed_description *const format,
|
|
const struct pvr_device_info *const dev_info)
|
|
{
|
|
if (PVR_HAS_FEATURE(dev_info, tpu_border_colour_enhanced)) {
|
|
const struct pvr_tex_format_description *format_simple =
|
|
pvr_get_tex_format_description(format->tex_format_simple);
|
|
|
|
pvr_border_color_table_pack_single(dst, color, format_simple, false);
|
|
return;
|
|
}
|
|
|
|
memset(dst->value, 0, sizeof(dst->value));
|
|
|
|
pvr_finishme("Devices without tpu_border_colour_enhanced require entries "
|
|
"for compressed formats to be stored in the table "
|
|
"pre-compressed.");
|
|
}
|
|
|
|
static int32_t
|
|
pvr_border_color_table_alloc_entry(struct pvr_border_color_table *const table)
|
|
{
|
|
/* BITSET_FFS() returns a 1-indexed position or 0 if no bits are set. */
|
|
int32_t index = BITSET_FFS(table->unused_entries);
|
|
if (!index--)
|
|
return -1;
|
|
|
|
BITSET_CLEAR(table->unused_entries, index);
|
|
|
|
return index;
|
|
}
|
|
|
|
static void
|
|
pvr_border_color_table_free_entry(struct pvr_border_color_table *const table,
|
|
const uint32_t index)
|
|
{
|
|
assert(pvr_border_color_table_is_index_valid(table, index));
|
|
BITSET_SET(table->unused_entries, index);
|
|
}
|
|
|
|
static void
|
|
pvr_border_color_table_fill_entry(struct pvr_border_color_table *const table,
|
|
const uint32_t index,
|
|
const union pipe_color_union *const color,
|
|
const bool is_int,
|
|
const struct pvr_device_info *const dev_info)
|
|
{
|
|
struct pvr_border_color_table_entry *const entries = table->table->bo->map;
|
|
struct pvr_border_color_table_entry *const entry = &entries[index];
|
|
uint32_t tex_format = 0;
|
|
|
|
for (; tex_format < PVR_TEX_FORMAT_COUNT; tex_format++) {
|
|
if (!pvr_tex_format_is_supported(tex_format))
|
|
continue;
|
|
|
|
pvr_border_color_table_pack_single(
|
|
&entry->values[tex_format],
|
|
color,
|
|
pvr_get_tex_format_description(tex_format),
|
|
is_int);
|
|
}
|
|
|
|
for (; tex_format < PVR_TEX_FORMAT_COUNT * 2; tex_format++) {
|
|
if (!pvr_tex_format_compressed_is_supported(tex_format))
|
|
continue;
|
|
|
|
pvr_border_color_table_pack_single_compressed(
|
|
&entry->values[tex_format],
|
|
color,
|
|
pvr_get_tex_format_compressed_description(tex_format),
|
|
dev_info);
|
|
}
|
|
}
|
|
|
|
VkResult pvr_border_color_table_init(struct pvr_border_color_table *const table,
|
|
struct pvr_device *const device)
|
|
{
|
|
const struct pvr_device_info *const dev_info = &device->pdevice->dev_info;
|
|
const uint32_t cache_line_size = rogue_get_slc_cache_line_size(dev_info);
|
|
const uint32_t table_size = sizeof(struct pvr_border_color_table_entry) *
|
|
PVR_BORDER_COLOR_TABLE_NR_ENTRIES;
|
|
|
|
VkResult result;
|
|
|
|
/* Initialize to ones so ffs can be used to find unused entries. */
|
|
BITSET_ONES(table->unused_entries);
|
|
|
|
result = pvr_bo_alloc(device,
|
|
device->heaps.general_heap,
|
|
table_size,
|
|
cache_line_size,
|
|
PVR_BO_ALLOC_FLAG_CPU_MAPPED,
|
|
&table->table);
|
|
if (result != VK_SUCCESS)
|
|
goto err_out;
|
|
|
|
BITSET_CLEAR_RANGE_INSIDE_WORD(table->unused_entries,
|
|
0,
|
|
PVR_BORDER_COLOR_TABLE_NR_BUILTIN_ENTRIES -
|
|
1);
|
|
|
|
for (uint32_t i = 0; i < PVR_BORDER_COLOR_TABLE_NR_BUILTIN_ENTRIES; i++) {
|
|
const VkClearColorValue color = vk_border_color_value(i);
|
|
const bool is_int = vk_border_color_is_int(i);
|
|
|
|
pvr_border_color_table_fill_entry(table,
|
|
i,
|
|
(const union pipe_color_union *)&color,
|
|
is_int,
|
|
dev_info);
|
|
}
|
|
|
|
pvr_bo_cpu_unmap(device, table->table);
|
|
|
|
return VK_SUCCESS;
|
|
|
|
err_out:
|
|
return result;
|
|
}
|
|
|
|
void pvr_border_color_table_finish(struct pvr_border_color_table *const table,
|
|
struct pvr_device *const device)
|
|
{
|
|
#if MESA_DEBUG
|
|
BITSET_SET_RANGE_INSIDE_WORD(table->unused_entries,
|
|
0,
|
|
PVR_BORDER_COLOR_TABLE_NR_BUILTIN_ENTRIES - 1);
|
|
BITSET_NOT(table->unused_entries);
|
|
assert(BITSET_IS_EMPTY(table->unused_entries));
|
|
#endif
|
|
|
|
pvr_bo_free(device, table->table);
|
|
}
|
|
|
|
VkResult pvr_border_color_table_get_or_create_entry(
|
|
UNUSED struct pvr_border_color_table *const table,
|
|
const struct pvr_sampler *const sampler,
|
|
uint32_t *const index_out)
|
|
{
|
|
const VkBorderColor vk_type = sampler->vk.border_color;
|
|
|
|
if (vk_type <= PVR_BORDER_COLOR_TABLE_NR_BUILTIN_ENTRIES) {
|
|
*index_out = vk_type;
|
|
return VK_SUCCESS;
|
|
}
|
|
|
|
pvr_finishme("VK_EXT_custom_border_color is currently unsupported.");
|
|
return vk_error(sampler, VK_ERROR_EXTENSION_NOT_PRESENT);
|
|
}
|