Expose texture loader in "video.h".

This commit is contained in:
Skyth 2024-11-21 16:26:05 +03:00
parent 661cf1d127
commit 3e0490fcec
3 changed files with 191 additions and 161 deletions

View file

@ -963,10 +963,7 @@ static bool DetectWine()
static constexpr size_t TEXTURE_DESCRIPTOR_SIZE = 65536; static constexpr size_t TEXTURE_DESCRIPTOR_SIZE = 65536;
static constexpr size_t SAMPLER_DESCRIPTOR_SIZE = 1024; static constexpr size_t SAMPLER_DESCRIPTOR_SIZE = 1024;
static std::unique_ptr<RenderTexture> g_imFontTexture; static std::unique_ptr<GuestTexture> g_imFontTexture;
static std::unique_ptr<RenderTextureView> g_imFontTextureView;
static uint32_t g_imFontTextureDescriptorIndex;
static bool g_imPendingBarrier = true;
static std::unique_ptr<RenderPipelineLayout> g_imPipelineLayout; static std::unique_ptr<RenderPipelineLayout> g_imPipelineLayout;
static std::unique_ptr<RenderPipeline> g_imPipeline; static std::unique_ptr<RenderPipeline> g_imPipeline;
static ImDrawDataSnapshot g_imSnapshot; static ImDrawDataSnapshot g_imSnapshot;
@ -1005,6 +1002,8 @@ static void CreateImGuiBackend()
OptionsMenu::Init(); OptionsMenu::Init();
ImGui_ImplSDL2_InitForOther(Window::s_pWindow); ImGui_ImplSDL2_InitForOther(Window::s_pWindow);
g_imFontTexture = std::make_unique<GuestTexture>(ResourceType::Texture);
uint8_t* pixels; uint8_t* pixels;
int width, height; int width, height;
io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height);
@ -1017,7 +1016,9 @@ static void CreateImGuiBackend()
textureDesc.mipLevels = 1; textureDesc.mipLevels = 1;
textureDesc.arraySize = 1; textureDesc.arraySize = 1;
textureDesc.format = RenderFormat::R8_UNORM; textureDesc.format = RenderFormat::R8_UNORM;
g_imFontTexture = g_device->createTexture(textureDesc);
g_imFontTexture->textureHolder = g_device->createTexture(textureDesc);
g_imFontTexture->texture = g_imFontTexture->textureHolder.get();
uint32_t rowPitch = (width + PITCH_ALIGNMENT - 1) & ~(PITCH_ALIGNMENT - 1); uint32_t rowPitch = (width + PITCH_ALIGNMENT - 1) & ~(PITCH_ALIGNMENT - 1);
uint32_t slicePitch = (rowPitch * height + PLACEMENT_ALIGNMENT - 1) & ~(PLACEMENT_ALIGNMENT - 1); uint32_t slicePitch = (rowPitch * height + PLACEMENT_ALIGNMENT - 1) & ~(PLACEMENT_ALIGNMENT - 1);
@ -1042,24 +1043,26 @@ static void CreateImGuiBackend()
ExecuteCopyCommandList([&] ExecuteCopyCommandList([&]
{ {
g_copyCommandList->barriers(RenderBarrierStage::COPY, RenderTextureBarrier(g_imFontTexture.get(), RenderTextureLayout::COPY_DEST)); g_copyCommandList->barriers(RenderBarrierStage::COPY, RenderTextureBarrier(g_imFontTexture->texture, RenderTextureLayout::COPY_DEST));
g_copyCommandList->copyTextureRegion( g_copyCommandList->copyTextureRegion(
RenderTextureCopyLocation::Subresource(g_imFontTexture.get(), 0), RenderTextureCopyLocation::Subresource(g_imFontTexture->texture, 0),
RenderTextureCopyLocation::PlacedFootprint(uploadBuffer.get(), RenderFormat::R8_UNORM, width, height, 1, rowPitch, 0)); RenderTextureCopyLocation::PlacedFootprint(uploadBuffer.get(), RenderFormat::R8_UNORM, width, height, 1, rowPitch, 0));
}); });
g_imFontTexture->layout = RenderTextureLayout::COPY_DEST;
RenderTextureViewDesc textureViewDesc; RenderTextureViewDesc textureViewDesc;
textureViewDesc.format = textureDesc.format; textureViewDesc.format = textureDesc.format;
textureViewDesc.dimension = RenderTextureViewDimension::TEXTURE_2D; textureViewDesc.dimension = RenderTextureViewDimension::TEXTURE_2D;
textureViewDesc.mipLevels = 1; textureViewDesc.mipLevels = 1;
textureViewDesc.componentMapping = RenderComponentMapping(RenderSwizzle::ONE, RenderSwizzle::ONE, RenderSwizzle::ONE, RenderSwizzle::R); textureViewDesc.componentMapping = RenderComponentMapping(RenderSwizzle::ONE, RenderSwizzle::ONE, RenderSwizzle::ONE, RenderSwizzle::R);
g_imFontTextureView = g_imFontTexture->createTextureView(textureViewDesc); g_imFontTexture->textureView = g_imFontTexture->texture->createTextureView(textureViewDesc);
g_imFontTextureDescriptorIndex = g_textureDescriptorAllocator.allocate(); g_imFontTexture->descriptorIndex = g_textureDescriptorAllocator.allocate();
g_textureDescriptorSet->setTexture(g_imFontTextureDescriptorIndex, g_imFontTexture.get(), RenderTextureLayout::SHADER_READ, g_imFontTextureView.get()); g_textureDescriptorSet->setTexture(g_imFontTexture->descriptorIndex, g_imFontTexture->texture, RenderTextureLayout::SHADER_READ, g_imFontTexture->textureView.get());
io.Fonts->SetTexID(ImTextureID(g_imFontTextureDescriptorIndex)); io.Fonts->SetTexID(g_imFontTexture.get());
RenderPipelineLayoutBuilder pipelineLayoutBuilder; RenderPipelineLayoutBuilder pipelineLayoutBuilder;
pipelineLayoutBuilder.begin(false, true); pipelineLayoutBuilder.begin(false, true);
@ -1596,12 +1599,6 @@ static void ProcDrawImGui(const RenderCommand& cmd)
{ {
auto& commandList = g_commandLists[g_frame]; auto& commandList = g_commandLists[g_frame];
if (g_imPendingBarrier)
{
commandList->barriers(RenderBarrierStage::GRAPHICS, RenderTextureBarrier(g_imFontTexture.get(), RenderTextureLayout::SHADER_READ));
g_imPendingBarrier = false;
}
commandList->setGraphicsPipelineLayout(g_imPipelineLayout.get()); commandList->setGraphicsPipelineLayout(g_imPipelineLayout.get());
commandList->setPipeline(g_imPipeline.get()); commandList->setPipeline(g_imPipeline.get());
commandList->setGraphicsDescriptorSet(g_textureDescriptorSet.get(), 0); commandList->setGraphicsDescriptorSet(g_textureDescriptorSet.get(), 0);
@ -1650,7 +1647,21 @@ static void ProcDrawImGui(const RenderCommand& cmd)
if (drawCmd.ClipRect.z <= drawCmd.ClipRect.x || drawCmd.ClipRect.w <= drawCmd.ClipRect.y) if (drawCmd.ClipRect.z <= drawCmd.ClipRect.x || drawCmd.ClipRect.w <= drawCmd.ClipRect.y)
continue; continue;
uint32_t descriptorIndex = uint32_t(drawCmd.GetTexID()); auto texture = reinterpret_cast<GuestTexture*>(drawCmd.TextureId);
uint32_t descriptorIndex = TEXTURE_DESCRIPTOR_NULL_TEXTURE_2D;
if (texture != nullptr)
{
if (texture->layout != RenderTextureLayout::SHADER_READ)
{
commandList->barriers(RenderBarrierStage::GRAPHICS | RenderBarrierStage::COPY,
RenderTextureBarrier(texture->texture, RenderTextureLayout::SHADER_READ));
texture->layout = RenderTextureLayout::SHADER_READ;
}
descriptorIndex = texture->descriptorIndex;
}
commandList->setGraphicsPushConstants(0, &descriptorIndex, offsetof(ImGuiPushConstants, texture2DDescriptorIndex), sizeof(descriptorIndex)); commandList->setGraphicsPushConstants(0, &descriptorIndex, offsetof(ImGuiPushConstants, texture2DDescriptorIndex), sizeof(descriptorIndex));
commandList->setScissors(RenderRect(int32_t(drawCmd.ClipRect.x), int32_t(drawCmd.ClipRect.y), int32_t(drawCmd.ClipRect.z), int32_t(drawCmd.ClipRect.w))); commandList->setScissors(RenderRect(int32_t(drawCmd.ClipRect.x), int32_t(drawCmd.ClipRect.y), int32_t(drawCmd.ClipRect.z), int32_t(drawCmd.ClipRect.w)));
commandList->drawIndexedInstanced(drawCmd.ElemCount, 1, drawCmd.IdxOffset, drawCmd.VtxOffset, 0); commandList->drawIndexedInstanced(drawCmd.ElemCount, 1, drawCmd.IdxOffset, drawCmd.VtxOffset, 0);
@ -3559,15 +3570,11 @@ static RenderFormat ConvertDXGIFormat(ddspp::DXGIFormat format)
} }
} }
static void MakePictureData(GuestPictureData* pictureData, uint8_t* data, uint32_t dataSize) static bool LoadTexture(GuestTexture& texture, uint8_t* data, size_t dataSize)
{
if ((pictureData->flags & 0x1) == 0)
{ {
ddspp::Descriptor ddsDesc; ddspp::Descriptor ddsDesc;
if (ddspp::decode_header(data, ddsDesc) != ddspp::Error) if (ddspp::decode_header(data, ddsDesc) != ddspp::Error)
{ {
const auto texture = g_userHeap.AllocPhysical<GuestTexture>(ResourceType::Texture);
RenderTextureDesc desc; RenderTextureDesc desc;
desc.dimension = ConvertTextureDimension(ddsDesc.type); desc.dimension = ConvertTextureDimension(ddsDesc.type);
desc.width = ddsDesc.width; desc.width = ddsDesc.width;
@ -3578,23 +3585,19 @@ static void MakePictureData(GuestPictureData* pictureData, uint8_t* data, uint32
desc.format = ConvertDXGIFormat(ddsDesc.format); desc.format = ConvertDXGIFormat(ddsDesc.format);
desc.flags = ddsDesc.type == ddspp::TextureType::Cubemap ? RenderTextureFlag::CUBE : RenderTextureFlag::NONE; desc.flags = ddsDesc.type == ddspp::TextureType::Cubemap ? RenderTextureFlag::CUBE : RenderTextureFlag::NONE;
texture->textureHolder = g_device->createTexture(desc); texture.textureHolder = g_device->createTexture(desc);
texture->texture = texture->textureHolder.get(); texture.texture = texture.textureHolder.get();
texture->layout = RenderTextureLayout::COPY_DEST; texture.layout = RenderTextureLayout::COPY_DEST;
#ifdef _DEBUG
texture->texture->setName(reinterpret_cast<char*>(g_memory.Translate(pictureData->name + 2)));
#endif
RenderTextureViewDesc viewDesc; RenderTextureViewDesc viewDesc;
viewDesc.format = desc.format; viewDesc.format = desc.format;
viewDesc.dimension = ConvertTextureViewDimension(ddsDesc.type); viewDesc.dimension = ConvertTextureViewDimension(ddsDesc.type);
viewDesc.mipLevels = ddsDesc.numMips; viewDesc.mipLevels = ddsDesc.numMips;
texture->textureView = texture->texture->createTextureView(viewDesc); texture.textureView = texture.texture->createTextureView(viewDesc);
texture->descriptorIndex = g_textureDescriptorAllocator.allocate(); texture.descriptorIndex = g_textureDescriptorAllocator.allocate();
g_textureDescriptorSet->setTexture(texture->descriptorIndex, texture->texture, RenderTextureLayout::SHADER_READ, texture->textureView.get()); g_textureDescriptorSet->setTexture(texture.descriptorIndex, texture.texture, RenderTextureLayout::SHADER_READ, texture.textureView.get());
texture->viewDimension = viewDesc.dimension; texture.viewDimension = viewDesc.dimension;
struct Slice struct Slice
{ {
@ -3660,20 +3663,19 @@ static void MakePictureData(GuestPictureData* pictureData, uint8_t* data, uint32
ExecuteCopyCommandList([&] ExecuteCopyCommandList([&]
{ {
g_copyCommandList->barriers(RenderBarrierStage::COPY, RenderTextureBarrier(texture->texture, RenderTextureLayout::COPY_DEST)); g_copyCommandList->barriers(RenderBarrierStage::COPY, RenderTextureBarrier(texture.texture, RenderTextureLayout::COPY_DEST));
for (size_t i = 0; i < slices.size(); i++) for (size_t i = 0; i < slices.size(); i++)
{ {
auto& slice = slices[i]; auto& slice = slices[i];
g_copyCommandList->copyTextureRegion( g_copyCommandList->copyTextureRegion(
RenderTextureCopyLocation::Subresource(texture->texture, i), RenderTextureCopyLocation::Subresource(texture.texture, i),
RenderTextureCopyLocation::PlacedFootprint(uploadBuffer.get(), desc.format, slice.width, slice.height, slice.depth, (slice.dstRowPitch * 8) / ddsDesc.bitsPerPixelOrBlock * ddsDesc.blockWidth, slice.dstOffset)); RenderTextureCopyLocation::PlacedFootprint(uploadBuffer.get(), desc.format, slice.width, slice.height, slice.depth, (slice.dstRowPitch * 8) / ddsDesc.bitsPerPixelOrBlock * ddsDesc.blockWidth, slice.dstOffset));
} }
}); });
pictureData->texture = g_memory.MapVirtual(texture); return true;
pictureData->type = 0;
} }
else else
{ {
@ -3682,14 +3684,13 @@ static void MakePictureData(GuestPictureData* pictureData, uint8_t* data, uint32
if (stbImage != nullptr) if (stbImage != nullptr)
{ {
const auto texture = g_userHeap.AllocPhysical<GuestTexture>(ResourceType::Texture); texture.textureHolder = g_device->createTexture(RenderTextureDesc::Texture2D(width, height, 1, RenderFormat::R8G8B8A8_UNORM));
texture->textureHolder = g_device->createTexture(RenderTextureDesc::Texture2D(width, height, 1, RenderFormat::R8G8B8A8_UNORM)); texture.texture = texture.textureHolder.get();
texture->texture = texture->textureHolder.get(); texture.viewDimension = RenderTextureViewDimension::TEXTURE_2D;
texture->viewDimension = RenderTextureViewDimension::TEXTURE_2D; texture.layout = RenderTextureLayout::COPY_DEST;
texture->layout = RenderTextureLayout::COPY_DEST;
texture->descriptorIndex = g_textureDescriptorAllocator.allocate(); texture.descriptorIndex = g_textureDescriptorAllocator.allocate();
g_textureDescriptorSet->setTexture(texture->descriptorIndex, texture->texture, RenderTextureLayout::SHADER_READ); g_textureDescriptorSet->setTexture(texture.descriptorIndex, texture.texture, RenderTextureLayout::SHADER_READ);
uint32_t rowPitch = (width * 4 + PITCH_ALIGNMENT - 1) & ~(PITCH_ALIGNMENT - 1); uint32_t rowPitch = (width * 4 + PITCH_ALIGNMENT - 1) & ~(PITCH_ALIGNMENT - 1);
uint32_t slicePitch = rowPitch * height; uint32_t slicePitch = rowPitch * height;
@ -3719,17 +3720,44 @@ static void MakePictureData(GuestPictureData* pictureData, uint8_t* data, uint32
ExecuteCopyCommandList([&] ExecuteCopyCommandList([&]
{ {
g_copyCommandList->barriers(RenderBarrierStage::COPY, RenderTextureBarrier(texture->texture, RenderTextureLayout::COPY_DEST)); g_copyCommandList->barriers(RenderBarrierStage::COPY, RenderTextureBarrier(texture.texture, RenderTextureLayout::COPY_DEST));
g_copyCommandList->copyTextureRegion( g_copyCommandList->copyTextureRegion(
RenderTextureCopyLocation::Subresource(texture->texture, 0), RenderTextureCopyLocation::Subresource(texture.texture, 0),
RenderTextureCopyLocation::PlacedFootprint(uploadBuffer.get(), RenderFormat::R8G8B8A8_UNORM, width, height, 1, rowPitch / 4, 0)); RenderTextureCopyLocation::PlacedFootprint(uploadBuffer.get(), RenderFormat::R8G8B8A8_UNORM, width, height, 1, rowPitch / 4, 0));
}); });
pictureData->texture = g_memory.MapVirtual(texture); return true;
pictureData->type = 0;
} }
} }
return false;
}
std::unique_ptr<GuestTexture> LoadTexture(uint8_t* data, size_t dataSize)
{
GuestTexture texture(ResourceType::Texture);
if (LoadTexture(texture, data, dataSize))
return std::make_unique<GuestTexture>(std::move(texture));
return nullptr;
}
static void MakePictureData(GuestPictureData* pictureData, uint8_t* data, uint32_t dataSize)
{
if ((pictureData->flags & 0x1) == 0)
{
GuestTexture texture(ResourceType::Texture);
if (LoadTexture(texture, data, dataSize))
{
#ifdef _DEBUG
texture.texture->setName(reinterpret_cast<char*>(g_memory.Translate(pictureData->name + 2)));
#endif
pictureData->texture = g_memory.MapVirtual(g_userHeap.AllocPhysical<GuestTexture>(std::move(texture)));
pictureData->type = 0;
}
} }
} }

View file

@ -357,3 +357,7 @@ enum GuestTextureAddress
D3DTADDRESS_MIRRORONCE = 3, D3DTADDRESS_MIRRORONCE = 3,
D3DTADDRESS_BORDER = 6 D3DTADDRESS_BORDER = 6
}; };
extern std::unique_ptr<GuestTexture> LoadTexture(uint8_t* data, size_t dataSize);
extern void VideoConfigValueChangedCallback(class IConfigDef* config);

View file

@ -4,6 +4,7 @@
#include <api/SWA/System/InputState.h> #include <api/SWA/System/InputState.h>
#include <gpu/imgui_common.h> #include <gpu/imgui_common.h>
#include <gpu/video.h>
#include <kernel/heap.h> #include <kernel/heap.h>
#include <kernel/memory.h> #include <kernel/memory.h>
#include <locale/locale.h> #include <locale/locale.h>
@ -501,9 +502,6 @@ static bool DrawCategories()
return false; return false;
} }
// extern definition to avoid including "video.h", the header is quite large
extern void VideoConfigValueChangedCallback(IConfigDef* config);
template<typename T> template<typename T>
static void DrawConfigOption(int32_t rowIndex, float yOffset, ConfigDef<T>* config, static void DrawConfigOption(int32_t rowIndex, float yOffset, ConfigDef<T>* config,
bool isAccessible, std::string* inaccessibleReason = nullptr, bool isAccessible, std::string* inaccessibleReason = nullptr,