Skip to content

Commit

Permalink
(Broken) texture rect locking
Browse files Browse the repository at this point in the history
  • Loading branch information
PazerOP committed May 21, 2019
1 parent a1adc0d commit c54876f
Show file tree
Hide file tree
Showing 17 changed files with 594 additions and 93 deletions.
3 changes: 1 addition & 2 deletions shaderapivulkan/shaderapivulkan.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@
<ClCompile Include="src\interface\internal\IShaderAPITexture.cpp" />
<ClCompile Include="src\interface\internal\IVulkanCommandBuffer.cpp" />
<ClCompile Include="include\TF2Vulkan\TextureData.cpp" />
<ClCompile Include="src\ShaderAPIVulkanDLL.cpp" />
<ClCompile Include="src\stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
Expand Down Expand Up @@ -183,4 +182,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
1 change: 0 additions & 1 deletion shaderapivulkan/src/ShaderAPIVulkanDLL.cpp

This file was deleted.

70 changes: 55 additions & 15 deletions shaderapivulkan/src/TF2Vulkan/FormatInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

#include <mutex>

#undef min
#undef max

using namespace TF2Vulkan;
using namespace TF2Vulkan::FormatInfo;

Expand Down Expand Up @@ -354,11 +357,6 @@ vk::Format FormatInfo::PromoteToHardware(vk::Format format, FormatUsage usage, b
}
}

vk::Extent2D FormatInfo::GetBlockSize(ImageFormat format)
{
return GetBlockSize(ConvertImageFormat(format));
}

vk::Extent2D FormatInfo::GetBlockSize(vk::Format format)
{
switch (format)
Expand Down Expand Up @@ -389,11 +387,6 @@ vk::Extent2D FormatInfo::GetBlockSize(vk::Format format)
}
}

size_t FormatInfo::GetPixelSize(ImageFormat format)
{
return GetPixelSize(ConvertImageFormat(format));
}

size_t FormatInfo::GetPixelSize(vk::Format format)
{
switch (format)
Expand All @@ -420,6 +413,58 @@ size_t FormatInfo::GetPixelSize(vk::Format format)
return 0;
}

uint32_t FormatInfo::GetStride(vk::Format format, uint32_t width)
{
return GetPixelSize(format) * width;
}

vk::Extent3D FormatInfo::GetMipResolution(uint_fast8_t mipIndex,
uint32_t inWidth, uint32_t inHeight, uint32_t inDepth)
{
return
{
std::max<uint32_t>(inWidth >> mipIndex, 1),
std::max<uint32_t>(inHeight >> mipIndex, 1),
std::max<uint32_t>(inDepth >> mipIndex, 1),
};
}

size_t FormatInfo::GetSliceSize(vk::Format format, uint32_t width, uint32_t height)
{
return GetStride(format, width) * height;
}

size_t FormatInfo::GetFrameSize3D(vk::Format format,
uint32_t width, uint32_t height, uint32_t depth,
uint_fast8_t mipCount, uint_fast8_t firstMip)
{
size_t retVal = 0;

for (uint_fast8_t i = 0; i < mipCount; i++)
{
const auto [mipW, mipH, mipD] = GetMipResolution(firstMip + i, width, height, depth);
retVal += GetSliceSize(format, mipW, mipH) * mipD;
}

return retVal;
}

FormatInfo::SubrectOffset FormatInfo::GetSubrectOffset(vk::Format format,
uint32_t offsetX, uint32_t offsetY, uint32_t offsetZ,
uint32_t width, uint32_t height, uint32_t depth,
uint_fast8_t mipLevel)
{
size_t offset = GetFrameSize3D(format, width, height, depth, mipLevel);

const auto [mipW, mipH, mipD] = GetMipResolution(mipLevel, width, height, depth);
const uint32_t pixelSize = FormatInfo::GetPixelSize(format);
const uint32_t mipStride = FormatInfo::GetStride(format, width);
const uint32_t mipSliceStride = FormatInfo::GetSliceSize(format, mipW, mipH);

offset += (mipSliceStride * offsetZ) + (mipStride * offsetY) + (pixelSize * offsetX);
return { offset, mipStride };
}

vk::ImageAspectFlags FormatInfo::GetAspects(const vk::Format& format)
{
switch (format)
Expand Down Expand Up @@ -516,11 +561,6 @@ vk::Format FormatInfo::ConvertDataFormat(DataFormat fmt, uint_fast8_t components
return vk::Format::eUndefined;
}

bool FormatInfo::IsCompressed(ImageFormat format)
{
return IsCompressed(ConvertImageFormat(format));
}

bool FormatInfo::IsCompressed(vk::Format format)
{
switch (format)
Expand Down
49 changes: 45 additions & 4 deletions shaderapivulkan/src/TF2Vulkan/FormatInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,60 @@ namespace TF2Vulkan{ namespace FormatInfo
vk::Format ConvertImageFormat(ImageFormat format);
ImageFormat ConvertImageFormat(vk::Format format);

bool IsCompressed(ImageFormat format);
bool IsCompressed(vk::Format format);
bool HasHardwareSupport(ImageFormat format, FormatUsage usage, bool filtering);
bool HasHardwareSupport(vk::Format format, FormatUsage usage, bool filtering);
bool HasHardwareSupport(ImageFormat format, FormatUsage usage, bool filtering);
ImageFormat PromoteToHardware(ImageFormat format, FormatUsage usage, bool filtering);
vk::Format PromoteToHardware(vk::Format format, FormatUsage usage, bool filtering);
vk::Extent2D GetBlockSize(ImageFormat format);
vk::Extent2D GetBlockSize(vk::Format format);
size_t GetPixelSize(ImageFormat format);
size_t GetPixelSize(vk::Format format);
size_t GetStride(vk::Format format, uint32_t width);
vk::Extent3D GetMipResolution(uint_fast8_t mipIndex, uint32_t width, uint32_t height, uint32_t depth = 1);
size_t GetSliceSize(vk::Format format, uint32_t width, uint32_t height);

size_t GetFrameSize3D(vk::Format format,
uint32_t width, uint32_t height, uint32_t depth,
uint_fast8_t mipCount = 1, uint_fast8_t firstMip = 0);

struct SubrectOffset
{
size_t m_Offset;
size_t m_Stride;
};
SubrectOffset GetSubrectOffset(vk::Format format,
uint32_t offsetX, uint32_t offsetY, uint32_t offsetZ,
uint32_t width, uint32_t height, uint32_t depth,
uint_fast8_t mipLevel = 0);

vk::ImageAspectFlags GetAspects(const vk::Format& format);

vk::Format ConvertDataFormat(DataFormat fmt, uint_fast8_t components, uint_fast8_t componentSize);
[[nodiscard]] bool ConvertDataFormat(vk::Format inFmt, DataFormat& outFmt, uint_fast8_t& numComponents, uint_fast8_t& byteSize);

inline size_t GetFrameSize2D(vk::Format format,
uint32_t width, uint32_t height,
uint_fast8_t mipCount = 1, uint_fast8_t firstMip = 0)
{
return GetFrameSize3D(format, width, height, 1, mipCount, firstMip);
}
inline vk::Extent2D GetBlockSize(ImageFormat format)
{
return GetBlockSize(ConvertImageFormat(format));
}
inline bool IsCompressed(ImageFormat format)
{
return IsCompressed(ConvertImageFormat(format));
}
inline size_t GetStride(ImageFormat format, uint32_t width)
{
return GetStride(ConvertImageFormat(format), width);
}
inline size_t GetPixelSize(ImageFormat format)
{
return GetPixelSize(ConvertImageFormat(format));
}
inline size_t GetSliceSize(ImageFormat format, uint32_t width, uint32_t height)
{
return GetSliceSize(ConvertImageFormat(format), width, height);
}
} }
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@ void IShaderAPI_StateManagerDynamic::UserClipTransform(const VMatrix& worldToVie
Util::SetDirtyVar(m_State.m_UserClipTransformOverride, worldToView, m_Dirty);
}

void IShaderAPI_StateManagerDynamic::SetSkinningMatrices()
{
LOG_FUNC();
// Just let shaders handle all uniform buffers (for now?)
}

void IShaderAPI_StateManagerDynamic::SetShaderInstance(ShaderType type, const IShaderInstance* instance)
{
assert(instance->GetGroup().GetShaderType() == type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ namespace TF2Vulkan
void EnableUserClipTransformOverride(bool enable) override final;
void UserClipTransform(const VMatrix& worldToView) override final;

void SetSkinningMatrices() override final;

// IShaderDynamicNext
void SetShaderInstance(ShaderType type, const IShaderInstance* instance) override final;
void BindUniformBuffer(const BufferPoolEntry& buf, UniformBufferIndex index) override final;
Expand Down
115 changes: 101 additions & 14 deletions shaderapivulkan/src/TF2Vulkan/IShaderAPI/IShaderAPI_TextureManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,41 @@ void IShaderAPI_TextureManager::TexMagFilter(ShaderAPITextureHandle_t texHandle,
}

IShaderAPITexture& IShaderAPI_TextureManager::CreateTexture(std::string&& dbgName, const vk::ImageCreateInfo& imgCI)
{
LOG_FUNC_MSG(dbgName);

vma::AllocationCreateInfo allocCI;
allocCI.usage = VMA_MEMORY_USAGE_GPU_ONLY;

return CreateTexture(std::move(dbgName), imgCI, allocCI);
}

IShaderAPITexture& IShaderAPI_TextureManager::CreateTexture(
std::string&& dbgName, const vk::ImageCreateInfo& imgCI, const vma::AllocationCreateInfo& allocCI)
{
return CreateTexture(std::move(Factories::ImageFactory{}
.SetCreateInfo(imgCI)
.SetAllocCreateInfo(allocCI)
.SetDebugName(dbgName)));
}

IShaderAPITexture& IShaderAPI_TextureManager::CreateTexture(Factories::ImageFactory&& factory)
{
const auto handle = m_NextTextureHandle++;
LOG_FUNC_TEX_NAME(handle, dbgName);

dbgName = Util::string::concat("[", handle, "] ", std::move(dbgName));
auto dbgName = Util::string::concat("[", handle, "] ", std::move(factory.m_DebugName));
factory.m_DebugName = Util::string::concat("Texture: ", dbgName);

auto createdImg = Factories::ImageFactory{}
.SetCreateInfo(imgCI)
.SetMemoryUsage(VMA_MEMORY_USAGE_GPU_ONLY)
.SetDebugName(Util::string::concat("Texture: ", dbgName))
.Create();
if (dbgName.find("readbacktex") != dbgName.npos)
__debugbreak();

return m_Textures.emplace(handle, ShaderTexture{ std::move(dbgName), handle, factory.m_CreateInfo, factory.Create() }).first->second;
}

return m_Textures.emplace(handle, ShaderTexture{ std::move(dbgName), handle, imgCI, std::move(createdImg) }).first->second;
IShaderAPITexture& IShaderAPI_TextureManager::CreateTexture(std::string&& dbgName, Factories::ImageFactory&& factory)
{
return CreateTexture(std::move(factory.SetDebugName(std::move(dbgName))));
}

ShaderAPITextureHandle_t IShaderAPI_TextureManager::CreateTexture(int width, int height, int depth,
Expand All @@ -102,7 +124,8 @@ ShaderAPITextureHandle_t IShaderAPI_TextureManager::CreateTexture(int width, int
ENSURE(depth > 0);
ENSURE(mipLevelCount > 0);

vk::ImageCreateInfo createInfo;
Factories::ImageFactory factory;
vk::ImageCreateInfo& createInfo = factory.m_CreateInfo;

// Don't actually use 1D textures, they cause issues
/*if (height == 1 && depth == 1)
Expand All @@ -119,7 +142,17 @@ ShaderAPITextureHandle_t IShaderAPI_TextureManager::CreateTexture(int width, int

createInfo.arrayLayers = 1; // No support for texture arrays in stock valve materialsystem
Util::SafeConvert(mipLevelCount, createInfo.mipLevels);
createInfo.usage = vk::ImageUsageFlagBits::eSampled;

vma::MemoryType memoryType = vma::MemoryType::eGpuOnly;
if (flags & TEXTURE_CREATE_SYSMEM)
{
factory.SetAllowMapping();
}
else
{
createInfo.usage |= vk::ImageUsageFlagBits::eSampled;
factory.SetMemoryType(vma::MemoryType::eGpuOnly);
}

if (flags & TEXTURE_CREATE_CUBEMAP)
createInfo.arrayLayers = 6;
Expand All @@ -131,7 +164,7 @@ ShaderAPITextureHandle_t IShaderAPI_TextureManager::CreateTexture(int width, int
if (flags & TEXTURE_CREATE_RENDERTARGET)
{
fmtUsage = FormatUsage::RenderTarget;
createInfo.usage |= vk::ImageUsageFlagBits::eColorAttachment;
createInfo.usage |= vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferSrc;
targetLayout = vk::ImageLayout::eColorAttachmentOptimal;
}
else if (flags & TEXTURE_CREATE_DEPTHBUFFER)
Expand All @@ -158,7 +191,7 @@ ShaderAPITextureHandle_t IShaderAPI_TextureManager::CreateTexture(int width, int
createInfo.extent.height += (blockSize.height - hDelta) % blockSize.height;
}

auto& newTex = CreateTexture(dbgName, createInfo);
auto& newTex = CreateTexture(dbgName, std::move(factory));

if (targetLayout != vk::ImageLayout::eUndefined)
{
Expand Down Expand Up @@ -270,7 +303,8 @@ void IShaderAPI_TextureManager::TexImageFromVTF(ShaderAPITextureHandle_t texHand

auto& tex = m_Textures.at(texHandle);

const auto mipCount = std::min(Util::SafeConvert<uint32_t>(vtf->MipCount()), tex.m_CreateInfo.mipLevels);
const auto mipCount = std::min(Util::SafeConvert<uint32_t>(vtf->MipCount()),
tex.GetImageCreateInfo().mipLevels);
ENSURE(mipCount > 0);

auto faceCount = vtf->FaceCount();
Expand Down Expand Up @@ -331,7 +365,7 @@ bool IShaderAPI_TextureManager::UpdateTexture(ShaderAPITextureHandle_t texHandle
}

auto& tex = m_Textures.at(texHandle);
const ImageFormat targetFormat = FormatInfo::ConvertImageFormat(tex.m_CreateInfo.format);
const ImageFormat targetFormat = FormatInfo::ConvertImageFormat(tex.GetImageCreateInfo().format);

auto& device = g_ShaderDevice.GetVulkanDevice();
auto& alloc = g_ShaderDevice.GetVulkanAllocator();
Expand Down Expand Up @@ -468,7 +502,7 @@ bool IShaderAPI_TextureManager::UpdateTexture(ShaderAPITextureHandle_t texHandle
barrier.dstAccessMask = vk::AccessFlagBits::eTransferWrite;

auto& srr = barrier.subresourceRange;
srr.aspectMask = FormatInfo::GetAspects(tex.m_CreateInfo.format);
srr.aspectMask = FormatInfo::GetAspects(tex.GetImageCreateInfo().format);
srr.baseMipLevel = slice.m_MipLevel;
srr.baseArrayLayer = slice.m_CubeFace;
srr.layerCount = 1;
Expand Down Expand Up @@ -536,6 +570,59 @@ void IShaderAPI_TextureManager::GetStandardTextureDimensions(int* width, int* he
Util::SafeConvert(ci.extent.height, *height);
}

void IShaderAPI_TextureManager::LockRect(void** outBits, int* outPitch, ShaderAPITextureHandle_t texID,
int mipLevel, int x, int y, int w, int h, bool write, bool read)
{
LOG_FUNC();

if (!outBits)
return;

auto& tex = m_Textures.at(texID);

auto& alloc = tex.m_Image.GetAllocation();
const auto& ci = tex.GetImageCreateInfo();

const auto [offset, stride] = FormatInfo::GetSubrectOffset(ci.format,
Util::SafeConvert<uint32_t>(x), Util::SafeConvert<uint32_t>(y), 0,
ci.extent.width, ci.extent.height, ci.extent.depth,
Util::SafeConvert<uint_fast8_t>(mipLevel));

if (outPitch)
Util::SafeConvert(stride, *outPitch);

auto& rect = tex.m_LockedRects.at(mipLevel);
if (auto mapped = alloc.data())
{
*outBits = alloc.data() + offset;
assert(!rect);
rect.m_IsDirectMapped = true;
}
else
{
// TODO: alternative slow path if texture is not mappable
NOT_IMPLEMENTED_FUNC();
}
}

void IShaderAPI_TextureManager::UnlockRect(ShaderAPITextureHandle_t texID, int mipLevel)
{
LOG_FUNC();

auto& tex = m_Textures.at(texID);
auto& rect = tex.m_LockedRects.at(mipLevel);
assert(rect);

if (rect.m_IsDirectMapped)
{
rect.m_IsDirectMapped = false;
}
else
{
NOT_IMPLEMENTED_FUNC();
}
}

void IShaderAPI_TextureManager::ModifyTexture(ShaderAPITextureHandle_t tex)
{
LOG_FUNC();
Expand Down
Loading

0 comments on commit c54876f

Please sign in to comment.