Skip to content

Commit

Permalink
Merge branch 'master' into vk-bestpractices-arm-lod-clamping
Browse files Browse the repository at this point in the history
  • Loading branch information
flyinghead authored Oct 9, 2024
2 parents b94a6e7 + a8bc1c1 commit 51abd6a
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 59 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ assignees: ''

Platform / OS / Hardware:

Github hash:
Flycast version:

Hardware:

Expand Down
27 changes: 14 additions & 13 deletions core/hw/pvr/ta_vtx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ class BaseTAParser

static void reset()
{
tileclip_val = 0;
memset(FaceBaseColor, 0xff, sizeof(FaceBaseColor));
memset(FaceOffsColor, 0xff, sizeof(FaceOffsColor));
memset(FaceBaseColor1, 0xff, sizeof(FaceBaseColor1));
Expand Down Expand Up @@ -398,7 +397,7 @@ case num : {\

//32B
case ParamType_User_Tile_Clip:
SetTileClip(data->data_32[3] & 63, data->data_32[4] & 31, data->data_32[5] & 63, data->data_32[6] & 31);
setClipRect(data->data_32[3] & 63, data->data_32[4] & 31, data->data_32[5] & 63, data->data_32[6] & 31);
data += SZ32;
break;

Expand All @@ -414,7 +413,7 @@ case num : {\
//PolyType :32B/64B
case ParamType_Polygon_or_Modifier_Volume:
{
TileClipMode(data->pcw.User_Clip);
setClipMode(data->pcw.User_Clip);
//Yep , C++ IS lame & limited
#include "ta_const_df.h"
if (CurrentList == ListType_None && !startList(data->pcw.ListType))
Expand Down Expand Up @@ -466,7 +465,7 @@ case num : {\
//32B
//Sets Sprite info , and switches to ta_sprite_data function
case ParamType_Sprite:
TileClipMode(data->pcw.User_Clip);
setClipMode(data->pcw.User_Clip);
if (CurrentList != ListType_None || startList(data->pcw.ListType))
{
VertexDataFP = ta_sprite_data;
Expand Down Expand Up @@ -502,23 +501,25 @@ case num : {\
{
TaCmd = ta_main;
BaseTAParser::reset();
setClipRect(0, 0, 39, 14);
setClipMode(0);
}

private:
static void SetTileClip(u32 xmin,u32 ymin,u32 xmax,u32 ymax)
static void setClipRect(u32 xmin, u32 ymin, u32 xmax, u32 ymax)
{
u32 rv=tileclip_val & 0xF0000000;
rv|=xmin; //6 bits
rv|=xmax<<6; //6 bits
rv|=ymin<<12; //5 bits
rv|=ymax<<17; //5 bits
tileclip_val=rv;
u32 rv = tileclip_val & 0xF0000000;
rv |= xmin; // 6 bits
rv |= xmax << 6; // 6 bits
rv |= ymin << 12; // 5 bits
rv |= ymax << 17; // 5 bits
tileclip_val = rv;
}

static void TileClipMode(u32 mode)
static void setClipMode(u32 mode)
{
//Group_En bit seems ignored, thanks p1pkin
tileclip_val=(tileclip_val&(~0xF0000000)) | (mode<<28);
tileclip_val = (tileclip_val & ~0xF0000000) | (mode << 28);
}

//Polys -- update code on sprites if that gets updated too --
Expand Down
25 changes: 24 additions & 1 deletion core/rend/vulkan/quad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,19 @@

#include <memory>

namespace {
size_t hashQuadVertex(const QuadVertex& vertex)
{
size_t seed = 0;
seed ^= std::hash<float>{}(vertex.x) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed ^= std::hash<float>{}(vertex.y) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed ^= std::hash<float>{}(vertex.z) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed ^= std::hash<float>{}(vertex.u) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed ^= std::hash<float>{}(vertex.v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
return seed;
}
}

static VulkanContext *GetContext()
{
return VulkanContext::Instance();
Expand Down Expand Up @@ -169,7 +182,7 @@ void QuadDrawer::Init(QuadPipeline *pipeline)
descSet.reset();
}

void QuadDrawer::Draw(vk::CommandBuffer commandBuffer, vk::ImageView imageView, QuadVertex vertices[], bool nearestFilter, const float *color)
void QuadDrawer::Draw(vk::CommandBuffer commandBuffer, vk::ImageView imageView, QuadVertex vertices[4], bool nearestFilter, const float *color)
{
VulkanContext *context = GetContext();
auto &descSet = descriptorSets[context->GetCurrentImageIndex()];
Expand Down Expand Up @@ -198,3 +211,13 @@ void QuadDrawer::Draw(vk::CommandBuffer commandBuffer, vk::ImageView imageView,
commandBuffer.pushConstants(pipeline->GetPipelineLayout(), vk::ShaderStageFlagBits::eFragment, 0, sizeof(float) * 4, color);
buffer->Draw(commandBuffer);
}

size_t QuadBuffer::hashQuadVertexData(QuadVertex vertices[4]) const
{
size_t seed = 0;
seed ^= hashQuadVertex(vertices[0]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed ^= hashQuadVertex(vertices[1]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed ^= hashQuadVertex(vertices[2]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed ^= hashQuadVertex(vertices[3]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
return seed;
}
21 changes: 18 additions & 3 deletions core/rend/vulkan/quad.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,37 @@ class QuadBuffer
commandBuffer.draw(4, 1, 0, 0);
}

void Update(QuadVertex vertices[] = nullptr)
void Update(QuadVertex vertices[4] = nullptr)
{
if (vertices == nullptr)
{
static QuadVertex defaultVtx[] {
static QuadVertex defaultVtx[4]
{
{ -1.f, -1.f, 0.f, 0.f, 0.f },
{ 1.f, -1.f, 0.f, 1.f, 0.f },
{ -1.f, 1.f, 0.f, 0.f, 1.f },
{ 1.f, 1.f, 0.f, 1.f, 1.f },
};
vertices = defaultVtx;
};

const size_t quadVerticesHash = hashQuadVertexData(vertices);;
if (quadVerticesHash == lastUploadHash)
{
// data already uploaded
return;
}

// new data to upload, update hash
lastUploadHash = quadVerticesHash;
buffer->upload(sizeof(QuadVertex) * 4, vertices);

}
private:
std::unique_ptr<BufferData> buffer;

size_t hashQuadVertexData(QuadVertex vertices[4]) const;
size_t lastUploadHash = 0;
};

class QuadPipeline
Expand Down Expand Up @@ -119,7 +134,7 @@ class QuadDrawer
QuadDrawer& operator=(const QuadDrawer &) = delete;

void Init(QuadPipeline *pipeline);
void Draw(vk::CommandBuffer commandBuffer, vk::ImageView imageView, QuadVertex vertices[] = nullptr, bool nearestFilter = false, const float *color = nullptr);
void Draw(vk::CommandBuffer commandBuffer, vk::ImageView imageView, QuadVertex vertices[4] = nullptr, bool nearestFilter = false, const float *color = nullptr);
private:
QuadPipeline *pipeline = nullptr;
std::unique_ptr<QuadBuffer> buffer;
Expand Down
7 changes: 6 additions & 1 deletion core/rend/vulkan/texture.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ class SamplerManager
const vk::SamplerAddressMode vRepeat = tsp.ClampV ? vk::SamplerAddressMode::eClampToEdge
: tsp.FlipV ? vk::SamplerAddressMode::eMirroredRepeat : vk::SamplerAddressMode::eRepeat;

// The W-axis is unused for 2D textures
// Try to keep all three of the wrapping-modes the same by just repeating vRepeat for wRepeat
// BestPractices-Arm-vkCreateSampler-different-wrapping-modes
const vk::SamplerAddressMode wRepeat = vRepeat;

const bool anisotropicFiltering = config::AnisotropicFiltering > 1 && VulkanContext::Instance()->SupportsSamplerAnisotropy()
&& filter == vk::Filter::eLinear && !punchThrough;
#ifndef __APPLE__
Expand All @@ -137,7 +142,7 @@ class SamplerManager
return samplers.emplace(
std::make_pair(samplerHash, VulkanContext::Instance()->GetDevice().createSamplerUnique(
vk::SamplerCreateInfo(vk::SamplerCreateFlags(), filter, filter,
mipmapMode, uRepeat, vRepeat, vk::SamplerAddressMode::eClampToEdge, mipLodBias,
mipmapMode, uRepeat, vRepeat, wRepeat, mipLodBias,
anisotropicFiltering, std::min((float)config::AnisotropicFiltering, VulkanContext::Instance()->GetMaxSamplerAnisotropy()),
false, vk::CompareOp::eNever,
0.0f, vk::LodClampNone, vk::BorderColor::eFloatOpaqueBlack)))).first->second.get();
Expand Down
2 changes: 1 addition & 1 deletion core/rend/vulkan/vk_context_lr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ void VulkanContext::PresentFrame(vk::Image image, vk::ImageView imageView, const
getVideoShift(shiftX, shiftY);

beginFrame(extent);
QuadVertex vtx[] {
QuadVertex vtx[4] {
{ -1, -1, 0, 0, 0 },
{ 1, -1, 0, 1, 0 },
{ -1, 1, 0, 0, 1 },
Expand Down
72 changes: 35 additions & 37 deletions core/rend/vulkan/vulkan_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,49 +407,47 @@ bool VulkanContext::InitDevice()
else
DEBUG_LOG(RENDERER, "Using distinct Graphics and Present queue families");

// Enable VK_KHR_dedicated_allocation if available
bool getMemReq2Supported = false;
dedicatedAllocationSupported = false;
std::vector<const char *> deviceExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
for (const auto& property : physicalDevice.enumerateDeviceExtensionProperties())

std::set<std::string> supportedExtensions;

const auto deviceExtensionProperties = physicalDevice.enumerateDeviceExtensionProperties();
for (const auto& property : deviceExtensionProperties)
{
if (!strcmp(property.extensionName, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME))
{
deviceExtensions.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
getMemReq2Supported = true;
}
else if (!strcmp(property.extensionName, VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME))
supportedExtensions.insert(property.extensionName);
}

std::vector<const char*> enabledExtensions;

const auto tryAddDeviceExtension = [&supportedExtensions = std::as_const(supportedExtensions), &enabledExtensions]
(std::string_view extensionName) -> bool
{
if (supportedExtensions.count(extensionName.data()))
{
deviceExtensions.push_back(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
dedicatedAllocationSupported = true;
enabledExtensions.push_back(extensionName.data());
NOTICE_LOG(RENDERER, "Device extension enabled: %s", extensionName.data());
return true;
}
NOTICE_LOG(RENDERER, "Device extension unavailable: %s", extensionName.data());
return false;
};

// Required swapchain extension
tryAddDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME);

// Enable VK_KHR_dedicated_allocation if available
const bool getMemReq2Supported = tryAddDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
dedicatedAllocationSupported = tryAddDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
dedicatedAllocationSupported &= getMemReq2Supported;

#ifdef VK_ENABLE_BETA_EXTENSIONS
else if (!strcmp(property.extensionName, VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME))
deviceExtensions.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME);
tryAddDeviceExtension(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME);
#endif
#ifdef VK_USE_PLATFORM_METAL_EXT
else if (!strcmp(property.extensionName, VK_EXT_METAL_OBJECTS_EXTENSION_NAME))
deviceExtensions.push_back(VK_EXT_METAL_OBJECTS_EXTENSION_NAME);
tryAddDeviceExtension(VK_EXT_METAL_OBJECTS_EXTENSION_NAME);
#endif
#ifdef VK_DEBUG
else if (!strcmp(property.extensionName, VK_EXT_DEBUG_MARKER_EXTENSION_NAME))
{
NOTICE_LOG(RENDERER, "Debug extension %s available", property.extensionName.data());
deviceExtensions.push_back(VK_EXT_DEBUG_MARKER_EXTENSION_NAME);
}
else if(!strcmp(property.extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME))
{
NOTICE_LOG(RENDERER, "Debug extension %s available", property.extensionName.data());
deviceExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
}
else if (!strcmp(property.extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME))
{
NOTICE_LOG(RENDERER, "Debug extension %s available", property.extensionName.data());
deviceExtensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
}
tryAddDeviceExtension(VK_EXT_DEBUG_MARKER_EXTENSION_NAME);
#endif
}
dedicatedAllocationSupported &= getMemReq2Supported;

// create a UniqueDevice
float queuePriority = 1.0f;
Expand All @@ -460,7 +458,7 @@ bool VulkanContext::InitDevice()
if (samplerAnisotropy)
features.samplerAnisotropy = true;
device = physicalDevice.createDeviceUnique(vk::DeviceCreateInfo(vk::DeviceCreateFlags(), deviceQueueCreateInfo,
nullptr, deviceExtensions, &features));
nullptr, enabledExtensions, &features));

#if VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1
VULKAN_HPP_DEFAULT_DISPATCHER.init(*device);
Expand Down Expand Up @@ -924,7 +922,7 @@ void VulkanContext::Present() noexcept

void VulkanContext::DrawFrame(vk::ImageView imageView, const vk::Extent2D& extent, float aspectRatio)
{
QuadVertex vtx[] {
QuadVertex vtx[4] {
{ -1, -1, 0, 0, 0 },
{ 1, -1, 0, 1, 0 },
{ -1, 1, 0, 0, 1 },
Expand Down Expand Up @@ -1314,7 +1312,7 @@ bool VulkanContext::GetLastFrame(std::vector<u8>& data, int& width, int& height)
pipeline.BindPipeline(*commandBuffer);

// Draw
QuadVertex vtx[] {
QuadVertex vtx[4] {
{ -1, -1, 0, 0, 0 },
{ 1, -1, 0, 1, 0 },
{ -1, 1, 0, 0, 1 },
Expand Down
4 changes: 2 additions & 2 deletions core/rend/vulkan/vulkan_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class VulkanDriver final : public ImGuiDriver
vk::SamplerMipmapMode::eNearest,
vk::SamplerAddressMode::eClampToBorder,
vk::SamplerAddressMode::eClampToBorder,
vk::SamplerAddressMode::eClampToEdge, 0.0f, false,
vk::SamplerAddressMode::eClampToBorder, 0.0f, false,
0.f, false, vk::CompareOp::eNever, 0.0f, vk::LodClampNone,
vk::BorderColor::eFloatTransparentBlack));
}
Expand All @@ -115,7 +115,7 @@ class VulkanDriver final : public ImGuiDriver
vk::SamplerMipmapMode::eLinear,
vk::SamplerAddressMode::eClampToBorder,
vk::SamplerAddressMode::eClampToBorder,
vk::SamplerAddressMode::eClampToEdge, 0.0f, false,
vk::SamplerAddressMode::eClampToBorder, 0.0f, false,
0.f, false, vk::CompareOp::eNever, 0.0f, vk::LodClampNone,
vk::BorderColor::eFloatTransparentBlack));
}
Expand Down

0 comments on commit 51abd6a

Please sign in to comment.