mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-09 04:38:30 +09:00
[Fix] (MG_Backend/DirectVulkan, MG_Backend/DirectGLES): fix vulkan program
cache, get EGLSurfaceSize on viewport = 0
This commit is contained in:
@@ -12,6 +12,9 @@
|
||||
#include "MG_Util/Converters/MGToStr/TextureEnumConverter.h"
|
||||
#include "MG_Util/Converters/MGToVk/TextureEnumConverter.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
@@ -316,6 +319,99 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
return true;
|
||||
}
|
||||
|
||||
static Bool ShouldDumpTextureUploadStats() {
|
||||
static const Bool enabled = [] {
|
||||
const char* value = std::getenv("MOBILEGL_TEXTURE_UPLOAD_STATS");
|
||||
return value != nullptr && value[0] != '\0' && std::strcmp(value, "0") != 0;
|
||||
}();
|
||||
return enabled;
|
||||
}
|
||||
|
||||
static void DumpTextureSyncStats(Int textureId, TextureInternalFormat format, TextureUploadTarget uploadTarget,
|
||||
Uint32 mipLevelCount, const IntVec3& texelSize, SizeT byteSize,
|
||||
Bool hasDirtyMipLevel) {
|
||||
if (!ShouldDumpTextureUploadStats()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::fprintf(stderr,
|
||||
"MOBILEGL_TEXTURE_SYNC_STATS texture=%d format=%s target=%s mips=%u size=%dx%dx%d "
|
||||
"bytes=%zu dirty=%d\n",
|
||||
textureId,
|
||||
MG_Util::ConvertTextureInternalFormatToString(format).c_str(),
|
||||
MG_Util::ConvertTextureUploadTargetToString(uploadTarget).c_str(),
|
||||
mipLevelCount,
|
||||
texelSize.x(),
|
||||
texelSize.y(),
|
||||
texelSize.z(),
|
||||
byteSize,
|
||||
hasDirtyMipLevel ? 1 : 0);
|
||||
}
|
||||
|
||||
static void DumpTextureUploadStats(Int textureId, TextureUploadTarget target, Uint32 level,
|
||||
const IntVec3& texelSize, const void* data, SizeT byteSize, Uint32 channels) {
|
||||
if (!ShouldDumpTextureUploadStats() || data == nullptr || byteSize == 0 || channels == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto* bytes = static_cast<const Uint8*>(data);
|
||||
Uint8 minValue = 255;
|
||||
Uint8 maxValue = 0;
|
||||
SizeT nonZero = 0;
|
||||
Uint64 sum = 0;
|
||||
Uint64 neighborDiff = 0;
|
||||
SizeT neighborCount = 0;
|
||||
|
||||
for (SizeT i = 0; i < byteSize; ++i) {
|
||||
minValue = std::min(minValue, bytes[i]);
|
||||
maxValue = std::max(maxValue, bytes[i]);
|
||||
nonZero += bytes[i] != 0 ? 1 : 0;
|
||||
sum += bytes[i];
|
||||
}
|
||||
|
||||
const SizeT width = static_cast<SizeT>(std::max(texelSize.x(), 0));
|
||||
const SizeT height = static_cast<SizeT>(std::max(texelSize.y(), 0));
|
||||
const SizeT pixelStride = channels;
|
||||
if (width > 1 && height > 0 && byteSize >= width * height * pixelStride) {
|
||||
for (SizeT y = 0; y < height; ++y) {
|
||||
const SizeT row = y * width * pixelStride;
|
||||
for (SizeT x = 1; x < width; ++x) {
|
||||
const SizeT prev = row + (x - 1) * pixelStride;
|
||||
const SizeT cur = row + x * pixelStride;
|
||||
for (SizeT c = 0; c < std::min<SizeT>(channels, 3); ++c) {
|
||||
neighborDiff += static_cast<Uint64>(
|
||||
std::abs(static_cast<Int>(bytes[cur + c]) - static_cast<Int>(bytes[prev + c])));
|
||||
++neighborCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const double avg = byteSize > 0 ? static_cast<double>(sum) / static_cast<double>(byteSize) : 0.0;
|
||||
const double avgNeighborDiff =
|
||||
neighborCount > 0 ? static_cast<double>(neighborDiff) / static_cast<double>(neighborCount) : 0.0;
|
||||
std::fprintf(stderr,
|
||||
"MOBILEGL_TEXTURE_UPLOAD_STATS texture=%d target=%s level=%u size=%dx%dx%d bytes=%zu "
|
||||
"channels=%u min=%u max=%u avg=%.2f nonzero=%zu neighborDiff=%.2f first=%u,%u,%u,%u\n",
|
||||
textureId,
|
||||
MG_Util::ConvertTextureUploadTargetToString(target).c_str(),
|
||||
level,
|
||||
texelSize.x(),
|
||||
texelSize.y(),
|
||||
texelSize.z(),
|
||||
byteSize,
|
||||
channels,
|
||||
static_cast<Uint>(minValue),
|
||||
static_cast<Uint>(maxValue),
|
||||
avg,
|
||||
nonZero,
|
||||
avgNeighborDiff,
|
||||
byteSize > 0 ? static_cast<Uint>(bytes[0]) : 0u,
|
||||
byteSize > 1 ? static_cast<Uint>(bytes[1]) : 0u,
|
||||
byteSize > 2 ? static_cast<Uint>(bytes[2]) : 0u,
|
||||
byteSize > 3 ? static_cast<Uint>(bytes[3]) : 0u);
|
||||
}
|
||||
|
||||
static VkComponentSwizzle ToVkComponentSwizzle(TextureSwizzleParam swizzle) {
|
||||
switch (swizzle) {
|
||||
case TextureSwizzleParam::Red:
|
||||
@@ -777,6 +873,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
break;
|
||||
}
|
||||
}
|
||||
DumpTextureSyncStats(texture.GetExternalIndex(), texture.GetFormat(), uploadTarget, mipLevelCount,
|
||||
texelSize, byteSize, hasDirtyMipLevel);
|
||||
if (!hasDirtyMipLevel) {
|
||||
return true;
|
||||
}
|
||||
@@ -1001,6 +1099,12 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
DeferViewRelease(resource.fullView);
|
||||
resource.fullView = VK_NULL_HANDLE;
|
||||
}
|
||||
for (auto& sampledView : resource.perMipSampledViews) {
|
||||
if (sampledView != VK_NULL_HANDLE) {
|
||||
DeferViewRelease(sampledView);
|
||||
sampledView = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
const TextureFormatInfo formatInfo = ResolveTextureFormatInfo(texture.GetFormat());
|
||||
const VkComponentMapping sampledComponents = ResolveSampledViewComponents(texture, formatInfo);
|
||||
@@ -1111,6 +1215,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
if (!uploadItems.back().expandedData.empty()) {
|
||||
uploadItems.back().source = uploadItems.back().expandedData.data();
|
||||
}
|
||||
DumpTextureUploadStats(mipmapTexture.GetExternalIndex(), uploadItems.back().target,
|
||||
uploadItems.back().level, uploadItems.back().texelSize,
|
||||
uploadItems.back().source, uploadItems.back().uploadByteSize,
|
||||
formatInfo.expandRgbToRgba ? 4u : 0u);
|
||||
stagingSize += static_cast<VkDeviceSize>(uploadItems.back().uploadByteSize);
|
||||
}
|
||||
}
|
||||
@@ -1156,16 +1264,17 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
VK_VERIFY(vkBeginCommandBuffer(commandBuffer, &beginInfo), "vkBeginCommandBuffer(texture)");
|
||||
|
||||
const VkImageAspectFlags aspectMask = GetAspectMaskForFormat(outResource.format);
|
||||
VkPipelineStageFlags uploadSrcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||
VkAccessFlags uploadSrcAccessMask = 0;
|
||||
GetImageTransitionSourceState(outResource.layout, uploadSrcStageMask, uploadSrcAccessMask);
|
||||
Bool ok = TransitionImageLayout(commandBuffer, outResource.image,
|
||||
outResource.layout,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
outResource.layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL ?
|
||||
kGraphicsSampledReadStages :
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
outResource.layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL ? VK_ACCESS_SHADER_READ_BIT : 0,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
aspectMask, 0, outResource.mipLevels, outResource.arrayLayers);
|
||||
outResource.layout,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
uploadSrcStageMask,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
uploadSrcAccessMask,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
aspectMask, 0, outResource.mipLevels, outResource.arrayLayers);
|
||||
MOBILEGL_ASSERT(ok, "TransitionImageLayout to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL failed");
|
||||
|
||||
for (const auto& item : uploadItems) {
|
||||
|
||||
Reference in New Issue
Block a user