Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class PresentationScaler {
std::uint32_t sourceHeight = 0;
VkImage sourceImage = VK_NULL_HANDLE;
VkDeviceMemory sourceMemory = VK_NULL_HANDLE;
VkDeviceSize sourceBytes = 0;
std::uint32_t sourceMemoryType = 0;
VkImage blackImage = VK_NULL_HANDLE;
VkDeviceMemory blackMemory = VK_NULL_HANDLE;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "prx/libSceAgcDriver/Execution/include/PresentationScaler.hpp"
#include "prx/libSceAgcDriver/Execution/include/AspectFit.hpp"
#include "prx/libSceAgcDriver/Graphics/include/BufferPool.hpp"
#include "prx/libSceAgcDriver/Graphics/include/Resources.hpp"

namespace AgcDriver {
Expand All @@ -23,7 +24,7 @@ PresentationScaler::~PresentationScaler() {

void PresentationScaler::release() noexcept {
if (sourceImage != VK_NULL_HANDLE) context.Function<PFN_vkDestroyImage>("vkDestroyImage")(context.device, sourceImage, nullptr);
if (sourceMemory != VK_NULL_HANDLE) context.Function<PFN_vkFreeMemory>("vkFreeMemory")(context.device, sourceMemory, nullptr);
if (sourceMemory != VK_NULL_HANDLE) Graphics::ReleaseImageMemory(context, sourceMemory, sourceBytes, sourceMemoryType);
sourceImage = VK_NULL_HANDLE;
sourceMemory = VK_NULL_HANDLE;
sourceWidth = 0;
Expand All @@ -50,8 +51,9 @@ void PresentationScaler::EnsureSourceImage(std::uint32_t width, std::uint32_t he
context.Function<PFN_vkGetImageMemoryRequirements>("vkGetImageMemoryRequirements")(context.device, sourceImage, &requirements);
VkMemoryAllocateInfo allocation{VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
allocation.allocationSize = requirements.size;
allocation.memoryTypeIndex = context.MemoryType(requirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
Graphics::Check(context.Function<PFN_vkAllocateMemory>("vkAllocateMemory")(context.device, &allocation, nullptr, &sourceMemory), "vkAllocateMemory presentation source");
allocation.memoryTypeIndex = context.DeviceMemoryType(requirements.memoryTypeBits, requirements.size, "presentation source");
sourceMemory = Graphics::AllocateImageMemory(context, allocation, requirements.memoryTypeBits, "vkAllocateMemory presentation source", &sourceMemoryType, true);
sourceBytes = requirements.size;
Graphics::Check(context.Function<PFN_vkBindImageMemory>("vkBindImageMemory")(context.device, sourceImage, sourceMemory, 0), "vkBindImageMemory presentation source");
sourceWidth = width;
sourceHeight = height;
Expand Down
59 changes: 59 additions & 0 deletions core/libs/prx/libSceAgcDriver/tests/PresentationPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,64 @@ void residentPresentTests(const Context& context) {
blitLetterboxMatchesClear(context);
}

PFN_vkGetDeviceProcAddr realDeviceProc = nullptr;
PFN_vkAllocateMemory realAllocateMemory = nullptr;
const VkPhysicalDeviceMemoryProperties* refusingMemory = nullptr;
std::uint32_t refusedAllocations = 0;
std::uint32_t lastAllocatedType = UINT32_MAX;

VKAPI_ATTR VkResult VKAPI_CALL refuseDeviceLocalAllocation(VkDevice device, const VkMemoryAllocateInfo* info, const VkAllocationCallbacks* callbacks, VkDeviceMemory* memory) {
const auto heap = refusingMemory->memoryTypes[info->memoryTypeIndex].heapIndex;
if ((refusingMemory->memoryHeaps[heap].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) != 0) {
++refusedAllocations;
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
}
lastAllocatedType = info->memoryTypeIndex;
return realAllocateMemory(device, info, callbacks, memory);
}

VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL refusingDeviceProc(VkDevice device, const char* name) {
if (std::strcmp(name, "vkAllocateMemory") == 0) return reinterpret_cast<PFN_vkVoidFunction>(&refuseDeviceLocalAllocation);
return realDeviceProc(device, name);
}

void sourceImageOutsideDeviceMemoryTests(const Context& base) {
VkImageCreateInfo probeInfo{VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
probeInfo.imageType = VK_IMAGE_TYPE_2D;
probeInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
probeInfo.extent = {64u, 64u, 1u};
probeInfo.mipLevels = 1;
probeInfo.arrayLayers = 1;
probeInfo.samples = VK_SAMPLE_COUNT_1_BIT;
probeInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
probeInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
VkImage probe = VK_NULL_HANDLE;
Check(base.Function<PFN_vkCreateImage>("vkCreateImage")(base.device, &probeInfo, nullptr, &probe), "vkCreateImage probe");
VkMemoryRequirements requirements{};
base.Function<PFN_vkGetImageMemoryRequirements>("vkGetImageMemoryRequirements")(base.device, probe, &requirements);
base.Function<PFN_vkDestroyImage>("vkDestroyImage")(base.device, probe, nullptr);
if (!base.HostMemoryType(requirements.memoryTypeBits)) {
std::printf("presentation source in host memory: skipped, the device offers no host memory type for the image\n");
return;
}
auto context = base;
context.bufferPool.reset();
realDeviceProc = base.deviceProc;
realAllocateMemory = base.Function<PFN_vkAllocateMemory>("vkAllocateMemory");
refusingMemory = &context.memory;
refusedAllocations = 0;
lastAllocatedType = UINT32_MAX;
context.deviceProc = refusingDeviceProc;
{
PresentationScaler scaler(context, VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM);
scaler.EnsureSourceImage(64u, 64u);
Require(refusedAllocations != 0, "the presentation source never asked for device-local memory");
Require(lastAllocatedType != UINT32_MAX && (context.memory.memoryHeaps[context.memory.memoryTypes[lastAllocatedType].heapIndex].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) == 0, "the presentation source was not placed in host memory when device-local memory was refused");
Require(scaler.SourceWidth() == 64u && scaler.SourceHeight() == 64u, "the presentation source in host memory lost its extent");
}
context.bufferPool.reset();
}

}

int main() {
Expand All @@ -582,6 +640,7 @@ int main() {
return VulkanTestSkipped;
}
residentPresentTests(device->GetContext());
sourceImageOutsideDeviceMemoryTests(device->GetContext());
std::cout << "resident present format, presentation pass and letterbox tests passed\n";
return 0;
} catch (const std::exception& error) {
Expand Down
Loading