mirror of https://github.com/AxioDL/boo.git
MSAA and Anisotropic filtering variables
This commit is contained in:
parent
872ab3900d
commit
4257fc0b10
|
@ -61,6 +61,7 @@ ApplicationRun(IApplication::EPlatformType platform,
|
|||
SystemStringView friendlyName,
|
||||
SystemStringView pname,
|
||||
const std::vector<SystemString>& args,
|
||||
std::string_view gfxApi = {},
|
||||
uint32_t samples = 1,
|
||||
uint32_t anisotropy = 1,
|
||||
bool singleInstance=true);
|
||||
|
@ -72,6 +73,7 @@ ApplicationRun(IApplication::EPlatformType platform,
|
|||
SystemStringView uniqueName,
|
||||
SystemStringView friendlyName,
|
||||
int argc, const SystemChar** argv,
|
||||
std::string_view gfxApi = {},
|
||||
uint32_t samples = 1,
|
||||
uint32_t anisotropy = 1,
|
||||
bool singleInstance=true)
|
||||
|
@ -82,7 +84,7 @@ ApplicationRun(IApplication::EPlatformType platform,
|
|||
for (int i=1 ; i<argc ; ++i)
|
||||
args.push_back(argv[i]);
|
||||
return ApplicationRun(platform, cb, uniqueName, friendlyName, argv[0], args,
|
||||
samples, anisotropy, singleInstance);
|
||||
gfxApi, samples, anisotropy, singleInstance);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -45,7 +45,6 @@ struct VulkanContext
|
|||
VkRenderPass m_pass;
|
||||
VkCommandPool m_loadPool;
|
||||
VkCommandBuffer m_loadCmdBuf;
|
||||
VkSampler m_linearSamplers[3];
|
||||
VkFormat m_displayFormat;
|
||||
|
||||
struct Window
|
||||
|
@ -85,6 +84,12 @@ struct VulkanContext
|
|||
};
|
||||
std::unordered_map<const boo::IWindow*, std::unique_ptr<Window>> m_windows;
|
||||
|
||||
VkSampleCountFlags m_sampleCountColor = VK_SAMPLE_COUNT_1_BIT;
|
||||
VkSampleCountFlags m_sampleCountDepth = VK_SAMPLE_COUNT_1_BIT;
|
||||
float m_anisotropy = 1.f;
|
||||
|
||||
std::unordered_map<uint32_t, VkSampler> m_samplers;
|
||||
|
||||
bool initVulkan(std::string_view appName);
|
||||
bool enumerateDevices();
|
||||
void initDevice();
|
||||
|
|
|
@ -158,6 +158,8 @@ class D3D11TextureS : public GraphicsDataNode<ITextureS>
|
|||
upData[i].pSysMem = dataIt;
|
||||
upData[i].SysMemPitch = width * pxPitchNum / pxPitchDenom;
|
||||
upData[i].SysMemSlicePitch = upData[i].SysMemPitch * height;
|
||||
if (compressed)
|
||||
upData[i].SysMemPitch = width * 2;
|
||||
dataIt += upData[i].SysMemSlicePitch;
|
||||
if (width > 1)
|
||||
width /= 2;
|
||||
|
@ -1119,7 +1121,8 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
|
|||
{
|
||||
if (tex->m_samples > 1)
|
||||
{
|
||||
m_deferredCtx->CopyResource(tex->m_colorBindTex[bindIdx].Get(), tex->m_colorTex.Get());
|
||||
m_deferredCtx->ResolveSubresource(tex->m_colorBindTex[bindIdx].Get(), 0, tex->m_colorTex.Get(), 0,
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1133,7 +1136,15 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
|
|||
}
|
||||
if (depth && tex->m_depthBindCount)
|
||||
{
|
||||
m_deferredCtx->CopyResource(tex->m_depthBindTex[bindIdx].Get(), tex->m_depthTex.Get());
|
||||
if (tex->m_samples > 1)
|
||||
{
|
||||
m_deferredCtx->ResolveSubresource(tex->m_depthBindTex[bindIdx].Get(), 0, tex->m_depthTex.Get(), 0,
|
||||
DXGI_FORMAT_D24_UNORM_S8_UINT);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_deferredCtx->CopyResource(tex->m_depthBindTex[bindIdx].Get(), tex->m_depthTex.Get());
|
||||
}
|
||||
}
|
||||
|
||||
if (clearDepth)
|
||||
|
@ -1230,12 +1241,16 @@ class D3D11DataFactory : public ID3DDataFactory, public GraphicsDataFactoryHead
|
|||
struct D3D11Context* m_ctx;
|
||||
std::unordered_map<uint64_t, std::unique_ptr<D3D11ShareableShader>> m_sharedShaders;
|
||||
std::unordered_map<uint64_t, uint64_t> m_sourceToBinary;
|
||||
uint32_t m_sampleCount;
|
||||
|
||||
public:
|
||||
D3D11DataFactory(IGraphicsContext* parent, D3D11Context* ctx, uint32_t sampleCount)
|
||||
: m_parent(parent), m_ctx(ctx), m_sampleCount(sampleCount)
|
||||
{}
|
||||
D3D11DataFactory(IGraphicsContext* parent, D3D11Context* ctx)
|
||||
: m_parent(parent), m_ctx(ctx)
|
||||
{
|
||||
UINT qLevels;
|
||||
while (SUCCEEDED(ctx->m_dev->CheckMultisampleQualityLevels
|
||||
(DXGI_FORMAT_R8G8B8A8_UNORM, m_ctx->m_sampleCount, &qLevels)) && !qLevels)
|
||||
m_ctx->m_sampleCount = flp2(m_ctx->m_sampleCount - 1);
|
||||
}
|
||||
|
||||
Platform platform() const {return Platform::D3D11;}
|
||||
const SystemChar* platformName() const {return _S("D3D11");}
|
||||
|
@ -1283,7 +1298,7 @@ public:
|
|||
boo::ObjToken<ITextureR> newRenderTexture(size_t width, size_t height, TextureClampMode clampMode,
|
||||
size_t colorBindCount, size_t depthBindCount)
|
||||
{
|
||||
return {new D3D11TextureR(m_data, m_parent.m_ctx, width, height, m_parent.m_sampleCount,
|
||||
return {new D3D11TextureR(m_data, m_parent.m_ctx, width, height, m_parent.m_ctx->m_sampleCount,
|
||||
colorBindCount, depthBindCount)};
|
||||
}
|
||||
|
||||
|
@ -1293,7 +1308,7 @@ public:
|
|||
return {new struct D3D11VertexFormat(m_data, elementCount, elements)};
|
||||
}
|
||||
|
||||
#if _DEBUG
|
||||
#if _DEBUG && 0
|
||||
#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_DEBUG | D3DCOMPILE_OPTIMIZATION_LEVEL0
|
||||
#else
|
||||
#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_OPTIMIZATION_LEVEL3
|
||||
|
@ -1546,9 +1561,9 @@ IGraphicsCommandQueue* _NewD3D11CommandQueue(D3D11Context* ctx, D3D11Context::Wi
|
|||
return new D3D11CommandQueue(ctx, windowCtx, parent);
|
||||
}
|
||||
|
||||
IGraphicsDataFactory* _NewD3D11DataFactory(D3D11Context* ctx, IGraphicsContext* parent, uint32_t sampleCount)
|
||||
IGraphicsDataFactory* _NewD3D11DataFactory(D3D11Context* ctx, IGraphicsContext* parent)
|
||||
{
|
||||
return new D3D11DataFactory(parent, ctx, sampleCount);
|
||||
return new D3D11DataFactory(parent, ctx);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -228,6 +228,8 @@ class D3D12TextureS : public GraphicsDataNode<ITextureS>
|
|||
upData[i].pData = dataIt;
|
||||
upData[i].RowPitch = width * pxPitchNum / pxPitchDenom;
|
||||
upData[i].SlicePitch = upData[i].RowPitch * height;
|
||||
if (compressed)
|
||||
upData[i].RowPitch = width * 2;
|
||||
dataIt += upData[i].SlicePitch;
|
||||
if (width > 1)
|
||||
width /= 2;
|
||||
|
@ -446,9 +448,11 @@ class D3D12TextureR : public GraphicsDataNode<ITextureR>
|
|||
rtvDim = D3D12_RTV_DIMENSION_TEXTURE2DMS;
|
||||
dsvDim = D3D12_DSV_DIMENSION_TEXTURE2DMS;
|
||||
rtvresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, m_width, m_height, 1, 1, m_samples,
|
||||
0, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT);
|
||||
D3D11_STANDARD_MULTISAMPLE_PATTERN, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, D3D12_TEXTURE_LAYOUT_UNKNOWN,
|
||||
D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT);
|
||||
dsvresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R24G8_TYPELESS, m_width, m_height, 1, 1, m_samples,
|
||||
0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT);
|
||||
D3D11_STANDARD_MULTISAMPLE_PATTERN, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL, D3D12_TEXTURE_LAYOUT_UNKNOWN,
|
||||
D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -744,7 +748,8 @@ class D3D12ShaderPipeline : public GraphicsDataNode<IShaderPipeline>
|
|||
desc.NumRenderTargets = 1;
|
||||
desc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
desc.DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Count = ctx->m_sampleCount;
|
||||
desc.SampleDesc.Quality = D3D11_STANDARD_MULTISAMPLE_PATTERN;
|
||||
if (pipeline)
|
||||
{
|
||||
desc.CachedPSO.pCachedBlob = pipeline->GetBufferPointer();
|
||||
|
@ -1670,12 +1675,22 @@ class D3D12DataFactory : public ID3DDataFactory, public GraphicsDataFactoryHead
|
|||
struct D3D12Context* m_ctx;
|
||||
std::unordered_map<uint64_t, std::unique_ptr<D3D12ShareableShader>> m_sharedShaders;
|
||||
std::unordered_map<uint64_t, uint64_t> m_sourceToBinary;
|
||||
uint32_t m_sampleCount;
|
||||
|
||||
public:
|
||||
D3D12DataFactory(IGraphicsContext* parent, D3D12Context* ctx, uint32_t sampleCount)
|
||||
: m_parent(parent), m_ctx(ctx), m_sampleCount(sampleCount)
|
||||
D3D12DataFactory(IGraphicsContext* parent, D3D12Context* ctx)
|
||||
: m_parent(parent), m_ctx(ctx)
|
||||
{
|
||||
D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS qLevels = {};
|
||||
qLevels.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
qLevels.SampleCount = m_ctx->m_sampleCount;
|
||||
while (SUCCEEDED(ctx->m_dev->CheckFeatureSupport
|
||||
(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &qLevels, sizeof(qLevels))) &&
|
||||
!qLevels.NumQualityLevels)
|
||||
qLevels.SampleCount = flp2(qLevels.SampleCount - 1);
|
||||
m_ctx->m_sampleCount = qLevels.SampleCount;
|
||||
|
||||
m_ctx->m_anisotropy = std::min(m_ctx->m_anisotropy, uint32_t(16));
|
||||
|
||||
CD3DX12_DESCRIPTOR_RANGE ranges[] =
|
||||
{
|
||||
{D3D12_DESCRIPTOR_RANGE_TYPE_CBV, MAX_UNIFORM_COUNT, 0},
|
||||
|
@ -1689,11 +1704,12 @@ public:
|
|||
|
||||
D3D12_STATIC_SAMPLER_DESC samplers[] =
|
||||
{
|
||||
CD3DX12_STATIC_SAMPLER_DESC(0),
|
||||
CD3DX12_STATIC_SAMPLER_DESC(0, D3D12_FILTER_ANISOTROPIC, D3D12_TEXTURE_ADDRESS_MODE_WRAP,
|
||||
D3D12_TEXTURE_ADDRESS_MODE_WRAP, D3D12_TEXTURE_ADDRESS_MODE_WRAP, 0.f, m_ctx->m_anisotropy),
|
||||
CD3DX12_STATIC_SAMPLER_DESC(1, D3D12_FILTER_ANISOTROPIC, D3D12_TEXTURE_ADDRESS_MODE_BORDER,
|
||||
D3D12_TEXTURE_ADDRESS_MODE_BORDER, D3D12_TEXTURE_ADDRESS_MODE_BORDER),
|
||||
D3D12_TEXTURE_ADDRESS_MODE_BORDER, D3D12_TEXTURE_ADDRESS_MODE_BORDER, 0.f, m_ctx->m_anisotropy),
|
||||
CD3DX12_STATIC_SAMPLER_DESC(2, D3D12_FILTER_ANISOTROPIC, D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
|
||||
D3D12_TEXTURE_ADDRESS_MODE_CLAMP, D3D12_TEXTURE_ADDRESS_MODE_CLAMP)
|
||||
D3D12_TEXTURE_ADDRESS_MODE_CLAMP, D3D12_TEXTURE_ADDRESS_MODE_CLAMP, 0.f, m_ctx->m_anisotropy)
|
||||
};
|
||||
|
||||
ThrowIfFailed(D3D12SerializeRootSignaturePROC(
|
||||
|
@ -1758,7 +1774,7 @@ public:
|
|||
size_t colorBindCount, size_t depthBindCount)
|
||||
{
|
||||
D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent.m_parent->getCommandQueue());
|
||||
return {new D3D12TextureR(m_data, m_parent.m_ctx, q, width, height, m_parent.m_sampleCount,
|
||||
return {new D3D12TextureR(m_data, m_parent.m_ctx, q, width, height, m_parent.m_ctx->m_sampleCount,
|
||||
colorBindCount, depthBindCount)};
|
||||
}
|
||||
|
||||
|
@ -1769,7 +1785,7 @@ public:
|
|||
return {new struct D3D12VertexFormat(m_data, elementCount, elements)};
|
||||
}
|
||||
|
||||
#if _DEBUG
|
||||
#if _DEBUG && 0
|
||||
#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_DEBUG | D3DCOMPILE_OPTIMIZATION_LEVEL0
|
||||
#else
|
||||
#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_OPTIMIZATION_LEVEL3
|
||||
|
@ -2175,9 +2191,9 @@ IGraphicsCommandQueue* _NewD3D12CommandQueue(D3D12Context* ctx, D3D12Context::Wi
|
|||
return new struct D3D12CommandQueue(ctx, windowCtx, parent, cmdQueueOut);
|
||||
}
|
||||
|
||||
IGraphicsDataFactory* _NewD3D12DataFactory(D3D12Context* ctx, IGraphicsContext* parent, uint32_t sampleCount)
|
||||
IGraphicsDataFactory* _NewD3D12DataFactory(D3D12Context* ctx, IGraphicsContext* parent)
|
||||
{
|
||||
return new D3D12DataFactory(parent, ctx, sampleCount);
|
||||
return new D3D12DataFactory(parent, ctx);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -40,12 +40,11 @@ class VulkanDataFactoryImpl : public VulkanDataFactory, public GraphicsDataFacto
|
|||
friend struct VulkanPool;
|
||||
IGraphicsContext* m_parent;
|
||||
VulkanContext* m_ctx;
|
||||
uint32_t m_drawSamples;
|
||||
std::unordered_map<uint64_t, std::unique_ptr<VulkanShareableShader>> m_sharedShaders;
|
||||
std::vector<int> m_texUnis;
|
||||
public:
|
||||
std::unordered_map<uint64_t, uint64_t> m_sourceToBinary;
|
||||
VulkanDataFactoryImpl(IGraphicsContext* parent, VulkanContext* ctx, uint32_t drawSamples);
|
||||
VulkanDataFactoryImpl(IGraphicsContext* parent, VulkanContext* ctx);
|
||||
|
||||
Platform platform() const {return Platform::Vulkan;}
|
||||
const SystemChar* platformName() const {return _S("Vulkan");}
|
||||
|
@ -441,6 +440,10 @@ void VulkanContext::initDevice()
|
|||
VkPhysicalDeviceFeatures features = {};
|
||||
if (m_features.samplerAnisotropy)
|
||||
features.samplerAnisotropy = VK_TRUE;
|
||||
if (!m_features.textureCompressionBC)
|
||||
Log.report(logvisor::Fatal,
|
||||
"Vulkan device does not support DXT-format textures");
|
||||
features.textureCompressionBC = VK_TRUE;
|
||||
|
||||
VkDeviceCreateInfo deviceInfo = {};
|
||||
deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||
|
@ -469,7 +472,8 @@ void VulkanContext::initDevice()
|
|||
m_gpuProps.driverVersion & 0b111111111111);
|
||||
}
|
||||
|
||||
void VulkanContext::initSwapChain(VulkanContext::Window& windowCtx, VkSurfaceKHR surface, VkFormat format, VkColorSpaceKHR colorspace)
|
||||
void VulkanContext::initSwapChain(VulkanContext::Window& windowCtx, VkSurfaceKHR surface,
|
||||
VkFormat format, VkColorSpaceKHR colorspace)
|
||||
{
|
||||
m_displayFormat = format;
|
||||
VkSurfaceCapabilitiesKHR surfCapabilities;
|
||||
|
@ -590,32 +594,13 @@ void VulkanContext::initSwapChain(VulkanContext::Window& windowCtx, VkSurfaceKHR
|
|||
cmdBufBeginInfo.flags = 0;
|
||||
ThrowIfFailed(vk::BeginCommandBuffer(m_loadCmdBuf, &cmdBufBeginInfo));
|
||||
|
||||
/* Create shared linear sampler */
|
||||
VkSamplerCreateInfo samplerInfo = {};
|
||||
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
samplerInfo.pNext = nullptr;
|
||||
samplerInfo.magFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.minFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.maxAnisotropy = m_features.samplerAnisotropy ?
|
||||
m_gpuProps.limits.maxSamplerAnisotropy : 1.f;
|
||||
ThrowIfFailed(vk::CreateSampler(m_dev, &samplerInfo, nullptr, &m_linearSamplers[0]));
|
||||
m_sampleCountColor = flp2(std::min(m_gpuProps.limits.framebufferColorSampleCounts, m_sampleCountColor));
|
||||
m_sampleCountDepth = flp2(std::min(m_gpuProps.limits.framebufferDepthSampleCounts, m_sampleCountDepth));
|
||||
|
||||
/* Create shared white-clamped sampler */
|
||||
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||
samplerInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
|
||||
ThrowIfFailed(vk::CreateSampler(m_dev, &samplerInfo, nullptr, &m_linearSamplers[1]));
|
||||
|
||||
/* Create shared edge-clamped sampler */
|
||||
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
ThrowIfFailed(vk::CreateSampler(m_dev, &samplerInfo, nullptr, &m_linearSamplers[2]));
|
||||
if (m_features.samplerAnisotropy)
|
||||
m_anisotropy = std::min(m_gpuProps.limits.maxSamplerAnisotropy, m_anisotropy);
|
||||
else
|
||||
m_anisotropy = 1;
|
||||
|
||||
/* images */
|
||||
sc.m_bufs.resize(swapchainImageCount);
|
||||
|
@ -936,6 +921,50 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
static void MakeSampler(VulkanContext* ctx, VkSampler& sampOut, TextureClampMode mode, int mips)
|
||||
{
|
||||
uint32_t key = (uint32_t(mode) << 16) | mips;
|
||||
auto search = ctx->m_samplers.find(key);
|
||||
if (search != ctx->m_samplers.end())
|
||||
{
|
||||
sampOut = search->second;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create linear sampler */
|
||||
VkSamplerCreateInfo samplerInfo = {};
|
||||
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
samplerInfo.pNext = nullptr;
|
||||
samplerInfo.magFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.minFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
samplerInfo.anisotropyEnable = ctx->m_features.samplerAnisotropy;
|
||||
samplerInfo.maxAnisotropy = ctx->m_anisotropy;
|
||||
samplerInfo.maxLod = mips - 1;
|
||||
switch (mode)
|
||||
{
|
||||
case TextureClampMode::Repeat:
|
||||
default:
|
||||
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
break;
|
||||
case TextureClampMode::ClampToWhite:
|
||||
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||
samplerInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
|
||||
break;
|
||||
case TextureClampMode::ClampToEdge:
|
||||
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
break;
|
||||
}
|
||||
ThrowIfFailed(vk::CreateSampler(ctx->m_dev, &samplerInfo, nullptr, &sampOut));
|
||||
ctx->m_samplers[key] = sampOut;
|
||||
}
|
||||
|
||||
class VulkanTextureS : public GraphicsDataNode<ITextureS>
|
||||
{
|
||||
friend class VulkanDataFactory;
|
||||
|
@ -1022,7 +1051,7 @@ class VulkanTextureS : public GraphicsDataNode<ITextureS>
|
|||
texCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_gpuTex));
|
||||
|
||||
m_descInfo.sampler = ctx->m_linearSamplers[int(clampMode)];
|
||||
setClampMode(clampMode);
|
||||
m_descInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
}
|
||||
public:
|
||||
|
@ -1030,6 +1059,7 @@ public:
|
|||
VkDeviceMemory m_cpuMem;
|
||||
VkImage m_gpuTex;
|
||||
VkImageView m_gpuView = VK_NULL_HANDLE;
|
||||
VkSampler m_sampler = VK_NULL_HANDLE;
|
||||
VkDescriptorImageInfo m_descInfo;
|
||||
VkDeviceSize m_gpuOffset;
|
||||
~VulkanTextureS()
|
||||
|
@ -1044,7 +1074,8 @@ public:
|
|||
|
||||
void setClampMode(TextureClampMode mode)
|
||||
{
|
||||
m_descInfo.sampler = m_ctx->m_linearSamplers[int(mode)];
|
||||
MakeSampler(m_ctx, m_sampler, mode, m_mips);
|
||||
m_descInfo.sampler = m_sampler;
|
||||
}
|
||||
|
||||
void deleteUploadObjects()
|
||||
|
@ -1106,7 +1137,7 @@ public:
|
|||
size_t offset = 0;
|
||||
for (int i=0 ; i<regionCount ; ++i)
|
||||
{
|
||||
size_t srcRowPitch = width * m_pixelPitchNum / m_pixelPitchDenom;
|
||||
size_t regionPitch = width * height * m_pixelPitchNum / m_pixelPitchDenom;
|
||||
|
||||
copyRegions[i].imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
copyRegions[i].imageSubresource.mipLevel = i;
|
||||
|
@ -1121,7 +1152,7 @@ public:
|
|||
width /= 2;
|
||||
if (height > 1)
|
||||
height /= 2;
|
||||
offset += srcRowPitch;
|
||||
offset += regionPitch;
|
||||
}
|
||||
|
||||
/* Put the copy command into the command buffer */
|
||||
|
@ -1224,7 +1255,7 @@ class VulkanTextureSA : public GraphicsDataNode<ITextureSA>
|
|||
texCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_gpuTex));
|
||||
|
||||
m_descInfo.sampler = ctx->m_linearSamplers[int(clampMode)];
|
||||
setClampMode(clampMode);
|
||||
m_descInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
}
|
||||
public:
|
||||
|
@ -1232,6 +1263,7 @@ public:
|
|||
VkDeviceMemory m_cpuMem;
|
||||
VkImage m_gpuTex;
|
||||
VkImageView m_gpuView = VK_NULL_HANDLE;
|
||||
VkSampler m_sampler = VK_NULL_HANDLE;
|
||||
VkDescriptorImageInfo m_descInfo;
|
||||
VkDeviceSize m_gpuOffset;
|
||||
~VulkanTextureSA()
|
||||
|
@ -1246,7 +1278,8 @@ public:
|
|||
|
||||
void setClampMode(TextureClampMode mode)
|
||||
{
|
||||
m_descInfo.sampler = m_ctx->m_linearSamplers[int(mode)];
|
||||
MakeSampler(m_ctx, m_sampler, mode, m_mips);
|
||||
m_descInfo.sampler = m_sampler;
|
||||
}
|
||||
|
||||
void deleteUploadObjects()
|
||||
|
@ -1308,7 +1341,7 @@ public:
|
|||
size_t offset = 0;
|
||||
for (int i=0 ; i<regionCount ; ++i)
|
||||
{
|
||||
size_t srcRowPitch = width * m_layers * m_pixelPitchNum / m_pixelPitchDenom;
|
||||
size_t regionPitch = width * height * m_layers * m_pixelPitchNum / m_pixelPitchDenom;
|
||||
|
||||
copyRegions[i].imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
copyRegions[i].imageSubresource.mipLevel = i;
|
||||
|
@ -1323,7 +1356,7 @@ public:
|
|||
width /= 2;
|
||||
if (height > 1)
|
||||
height /= 2;
|
||||
offset += srcRowPitch;
|
||||
offset += regionPitch;
|
||||
}
|
||||
|
||||
/* Put the copy command into the command buffer */
|
||||
|
@ -1356,7 +1389,6 @@ class VulkanTextureD : public GraphicsDataNode<ITextureD>
|
|||
VulkanContext* m_ctx;
|
||||
std::unique_ptr<uint8_t[]> m_stagingBuf;
|
||||
size_t m_cpuSz;
|
||||
VkDeviceSize m_srcRowPitch;
|
||||
VkDeviceSize m_cpuOffsets[2];
|
||||
VkFormat m_vkFmt;
|
||||
int m_validSlots = 0;
|
||||
|
@ -1369,13 +1401,11 @@ class VulkanTextureD : public GraphicsDataNode<ITextureD>
|
|||
{
|
||||
case TextureFormat::RGBA8:
|
||||
pfmt = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
m_srcRowPitch = width * 4;
|
||||
m_cpuSz = m_srcRowPitch * height;
|
||||
m_cpuSz = width * height * 4;
|
||||
break;
|
||||
case TextureFormat::I8:
|
||||
pfmt = VK_FORMAT_R8_UNORM;
|
||||
m_srcRowPitch = width;
|
||||
m_cpuSz = m_srcRowPitch * height;
|
||||
m_cpuSz = width * height;
|
||||
break;
|
||||
default:
|
||||
Log.report(logvisor::Fatal, "unsupported tex format");
|
||||
|
@ -1436,6 +1466,7 @@ class VulkanTextureD : public GraphicsDataNode<ITextureD>
|
|||
texCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
texCreateInfo.flags = 0;
|
||||
|
||||
setClampMode(clampMode);
|
||||
for (int i=0 ; i<2 ; ++i)
|
||||
{
|
||||
/* bind cpu memory */
|
||||
|
@ -1444,7 +1475,7 @@ class VulkanTextureD : public GraphicsDataNode<ITextureD>
|
|||
/* create gpu image */
|
||||
ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_gpuTex[i]));
|
||||
|
||||
m_descInfo[i].sampler = ctx->m_linearSamplers[int(clampMode)];
|
||||
m_descInfo[i].sampler = m_sampler;
|
||||
m_descInfo[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
}
|
||||
}
|
||||
|
@ -1454,14 +1485,16 @@ public:
|
|||
VkDeviceMemory m_cpuMem;
|
||||
VkImage m_gpuTex[2];
|
||||
VkImageView m_gpuView[2];
|
||||
VkSampler m_sampler = VK_NULL_HANDLE;
|
||||
VkDeviceSize m_gpuOffset[2];
|
||||
VkDescriptorImageInfo m_descInfo[2];
|
||||
~VulkanTextureD();
|
||||
|
||||
void setClampMode(TextureClampMode mode)
|
||||
{
|
||||
MakeSampler(m_ctx, m_sampler, mode, 1);
|
||||
for (int i=0 ; i<2 ; ++i)
|
||||
m_descInfo[i].sampler = m_ctx->m_linearSamplers[int(mode)];
|
||||
m_descInfo[i].sampler = m_sampler;
|
||||
}
|
||||
|
||||
void load(const void* data, size_t sz);
|
||||
|
@ -1526,7 +1559,7 @@ class VulkanTextureR : public GraphicsDataNode<ITextureR>
|
|||
friend struct VulkanCommandQueue;
|
||||
size_t m_width = 0;
|
||||
size_t m_height = 0;
|
||||
size_t m_samples = 0;
|
||||
VkSampleCountFlags m_samplesColor, m_samplesDepth;
|
||||
|
||||
TextureClampMode m_clampMode;
|
||||
size_t m_colorBindCount;
|
||||
|
@ -1549,7 +1582,7 @@ class VulkanTextureR : public GraphicsDataNode<ITextureR>
|
|||
texCreateInfo.extent.depth = 1;
|
||||
texCreateInfo.mipLevels = 1;
|
||||
texCreateInfo.arrayLayers = 1;
|
||||
texCreateInfo.samples = VkSampleCountFlagBits(m_samples);
|
||||
texCreateInfo.samples = VkSampleCountFlagBits(m_samplesColor);
|
||||
texCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
texCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
texCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
|
@ -1560,6 +1593,7 @@ class VulkanTextureR : public GraphicsDataNode<ITextureR>
|
|||
ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_colorTex));
|
||||
|
||||
/* depth target */
|
||||
texCreateInfo.samples = VkSampleCountFlagBits(m_samplesDepth);
|
||||
texCreateInfo.format = VK_FORMAT_D32_SFLOAT;
|
||||
texCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_depthTex));
|
||||
|
@ -1603,7 +1637,7 @@ class VulkanTextureR : public GraphicsDataNode<ITextureR>
|
|||
memAlloc.allocationSize += memReqs.size;
|
||||
memTypeBits &= memReqs.memoryTypeBits;
|
||||
|
||||
m_colorBindDescInfo[i].sampler = ctx->m_linearSamplers[int(m_clampMode)];
|
||||
m_colorBindDescInfo[i].sampler = m_sampler;
|
||||
m_colorBindDescInfo[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
}
|
||||
|
||||
|
@ -1620,7 +1654,7 @@ class VulkanTextureR : public GraphicsDataNode<ITextureR>
|
|||
memAlloc.allocationSize += memReqs.size;
|
||||
memTypeBits &= memReqs.memoryTypeBits;
|
||||
|
||||
m_depthBindDescInfo[i].sampler = ctx->m_linearSamplers[int(m_clampMode)];
|
||||
m_depthBindDescInfo[i].sampler = m_sampler;
|
||||
m_depthBindDescInfo[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
}
|
||||
|
||||
|
@ -1709,10 +1743,12 @@ class VulkanTextureR : public GraphicsDataNode<ITextureR>
|
|||
VulkanContext* m_ctx;
|
||||
VulkanCommandQueue* m_q;
|
||||
VulkanTextureR(const boo::ObjToken<BaseGraphicsData>& parent, VulkanContext* ctx, VulkanCommandQueue* q,
|
||||
size_t width, size_t height, size_t samples, TextureClampMode clampMode,
|
||||
size_t width, size_t height, TextureClampMode clampMode,
|
||||
size_t colorBindCount, size_t depthBindCount)
|
||||
: GraphicsDataNode<ITextureR>(parent), m_ctx(ctx), m_q(q),
|
||||
m_width(width), m_height(height), m_samples(samples),
|
||||
m_width(width), m_height(height),
|
||||
m_samplesColor(ctx->m_sampleCountColor),
|
||||
m_samplesDepth(ctx->m_sampleCountDepth),
|
||||
m_clampMode(clampMode),
|
||||
m_colorBindCount(colorBindCount),
|
||||
m_depthBindCount(depthBindCount)
|
||||
|
@ -1722,11 +1758,12 @@ class VulkanTextureR : public GraphicsDataNode<ITextureR>
|
|||
if (depthBindCount > MAX_BIND_TEXS)
|
||||
Log.report(logvisor::Fatal, "too many depth bindings for render texture");
|
||||
|
||||
if (samples == 0) m_samples = 1;
|
||||
if (m_samplesColor == 0) m_samplesColor = 1;
|
||||
if (m_samplesDepth == 0) m_samplesDepth = 1;
|
||||
setClampMode(m_clampMode);
|
||||
Setup(ctx);
|
||||
}
|
||||
public:
|
||||
size_t samples() const {return m_samples;}
|
||||
VkDeviceMemory m_gpuMem = VK_NULL_HANDLE;
|
||||
|
||||
VkImage m_colorTex = VK_NULL_HANDLE;
|
||||
|
@ -1750,12 +1787,15 @@ public:
|
|||
VkImageLayout m_colorBindLayout[MAX_BIND_TEXS] = {};
|
||||
VkImageLayout m_depthBindLayout[MAX_BIND_TEXS] = {};
|
||||
|
||||
VkSampler m_sampler = VK_NULL_HANDLE;
|
||||
|
||||
void setClampMode(TextureClampMode mode)
|
||||
{
|
||||
MakeSampler(m_ctx, m_sampler, mode, 1);
|
||||
for (size_t i=0 ; i<m_colorBindCount ; ++i)
|
||||
m_colorBindDescInfo[i].sampler = m_ctx->m_linearSamplers[int(mode)];
|
||||
m_colorBindDescInfo[i].sampler = m_sampler;
|
||||
for (size_t i=0 ; i<m_depthBindCount ; ++i)
|
||||
m_depthBindDescInfo[i].sampler = m_ctx->m_linearSamplers[int(mode)];
|
||||
m_depthBindDescInfo[i].sampler = m_sampler;
|
||||
}
|
||||
|
||||
void doDestroy();
|
||||
|
@ -2006,7 +2046,7 @@ public:
|
|||
multisampleInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||
multisampleInfo.pNext = nullptr;
|
||||
multisampleInfo.flags = 0;
|
||||
multisampleInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
multisampleInfo.rasterizationSamples = VkSampleCountFlagBits(m_ctx->m_sampleCountColor);
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencilInfo = {};
|
||||
depthStencilInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||
|
@ -2738,7 +2778,7 @@ struct VulkanCommandQueue : IGraphicsCommandQueue
|
|||
SetImageLayout(cmdBuf, csource->m_colorTex, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1, 1);
|
||||
|
||||
if (csource->m_samples > 1)
|
||||
if (csource->m_samplesColor > 1)
|
||||
{
|
||||
VkImageResolve resolveInfo = {};
|
||||
resolveInfo.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
@ -2798,72 +2838,176 @@ struct VulkanCommandQueue : IGraphicsCommandQueue
|
|||
|
||||
vk::CmdEndRenderPass(cmdBuf);
|
||||
|
||||
VkImageCopy copyInfo = {};
|
||||
SWindowRect intersectRect = rect.intersect(SWindowRect(0, 0, ctexture->m_width, ctexture->m_height));
|
||||
copyInfo.srcOffset.y = tlOrigin ? intersectRect.location[1] :
|
||||
(ctexture->m_height - intersectRect.size[1] - intersectRect.location[1]);
|
||||
copyInfo.srcOffset.x = intersectRect.location[0];
|
||||
copyInfo.dstOffset = copyInfo.srcOffset;
|
||||
copyInfo.extent.width = intersectRect.size[0];
|
||||
copyInfo.extent.height = intersectRect.size[1];
|
||||
copyInfo.extent.depth = 1;
|
||||
copyInfo.dstSubresource.mipLevel = 0;
|
||||
copyInfo.dstSubresource.baseArrayLayer = 0;
|
||||
copyInfo.dstSubresource.layerCount = 1;
|
||||
copyInfo.srcSubresource.mipLevel = 0;
|
||||
copyInfo.srcSubresource.baseArrayLayer = 0;
|
||||
copyInfo.srcSubresource.layerCount = 1;
|
||||
|
||||
if (color && ctexture->m_colorBindCount)
|
||||
{
|
||||
if (ctexture == m_boundTarget.get())
|
||||
SetImageLayout(cmdBuf, ctexture->m_colorTex, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1, 1);
|
||||
if (ctexture->m_samplesColor <= 1)
|
||||
{
|
||||
VkImageCopy copyInfo = {};
|
||||
SWindowRect intersectRect = rect.intersect(SWindowRect(0, 0, ctexture->m_width, ctexture->m_height));
|
||||
copyInfo.srcOffset.y = tlOrigin ? intersectRect.location[1] :
|
||||
(ctexture->m_height - intersectRect.size[1] - intersectRect.location[1]);
|
||||
copyInfo.srcOffset.x = intersectRect.location[0];
|
||||
copyInfo.dstOffset = copyInfo.srcOffset;
|
||||
copyInfo.extent.width = intersectRect.size[0];
|
||||
copyInfo.extent.height = intersectRect.size[1];
|
||||
copyInfo.extent.depth = 1;
|
||||
copyInfo.dstSubresource.mipLevel = 0;
|
||||
copyInfo.dstSubresource.baseArrayLayer = 0;
|
||||
copyInfo.dstSubresource.layerCount = 1;
|
||||
copyInfo.srcSubresource.mipLevel = 0;
|
||||
copyInfo.srcSubresource.baseArrayLayer = 0;
|
||||
copyInfo.srcSubresource.layerCount = 1;
|
||||
|
||||
SetImageLayout(cmdBuf, ctexture->m_colorBindTex[bindIdx], VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
ctexture->m_colorBindLayout[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 1);
|
||||
if (ctexture == m_boundTarget.get())
|
||||
SetImageLayout(cmdBuf, ctexture->m_colorTex, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1, 1);
|
||||
|
||||
copyInfo.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
copyInfo.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
SetImageLayout(cmdBuf, ctexture->m_colorBindTex[bindIdx], VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
ctexture->m_colorBindLayout[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 1);
|
||||
|
||||
vk::CmdCopyImage(cmdBuf,
|
||||
ctexture->m_colorTex, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
ctexture->m_colorBindTex[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
1, ©Info);
|
||||
copyInfo.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
copyInfo.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
||||
if (ctexture == m_boundTarget.get())
|
||||
SetImageLayout(cmdBuf, ctexture->m_colorTex, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, 1);
|
||||
vk::CmdCopyImage(cmdBuf,
|
||||
ctexture->m_colorTex, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
ctexture->m_colorBindTex[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
1, ©Info);
|
||||
|
||||
SetImageLayout(cmdBuf, ctexture->m_colorBindTex[bindIdx], VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1, 1);
|
||||
ctexture->m_colorBindLayout[bindIdx] = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
if (ctexture == m_boundTarget.get())
|
||||
SetImageLayout(cmdBuf, ctexture->m_colorTex, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, 1);
|
||||
|
||||
SetImageLayout(cmdBuf, ctexture->m_colorBindTex[bindIdx], VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1, 1);
|
||||
ctexture->m_colorBindLayout[bindIdx] = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
VkImageResolve resolveInfo = {};
|
||||
SWindowRect intersectRect = rect.intersect(SWindowRect(0, 0, ctexture->m_width, ctexture->m_height));
|
||||
resolveInfo.srcOffset.y = tlOrigin ? intersectRect.location[1] :
|
||||
(ctexture->m_height - intersectRect.size[1] - intersectRect.location[1]);
|
||||
resolveInfo.srcOffset.x = intersectRect.location[0];
|
||||
resolveInfo.dstOffset = resolveInfo.srcOffset;
|
||||
resolveInfo.extent.width = intersectRect.size[0];
|
||||
resolveInfo.extent.height = intersectRect.size[1];
|
||||
resolveInfo.extent.depth = 1;
|
||||
resolveInfo.dstSubresource.mipLevel = 0;
|
||||
resolveInfo.dstSubresource.baseArrayLayer = 0;
|
||||
resolveInfo.dstSubresource.layerCount = 1;
|
||||
resolveInfo.srcSubresource.mipLevel = 0;
|
||||
resolveInfo.srcSubresource.baseArrayLayer = 0;
|
||||
resolveInfo.srcSubresource.layerCount = 1;
|
||||
|
||||
if (ctexture == m_boundTarget.get())
|
||||
SetImageLayout(cmdBuf, ctexture->m_colorTex, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1, 1);
|
||||
|
||||
SetImageLayout(cmdBuf, ctexture->m_colorBindTex[bindIdx], VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
ctexture->m_colorBindLayout[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 1);
|
||||
|
||||
resolveInfo.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
resolveInfo.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
||||
vk::CmdResolveImage(cmdBuf,
|
||||
ctexture->m_colorTex, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
ctexture->m_colorBindTex[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
1, &resolveInfo);
|
||||
|
||||
if (ctexture == m_boundTarget.get())
|
||||
SetImageLayout(cmdBuf, ctexture->m_colorTex, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, 1);
|
||||
|
||||
SetImageLayout(cmdBuf, ctexture->m_colorBindTex[bindIdx], VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1, 1);
|
||||
ctexture->m_colorBindLayout[bindIdx] = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (depth && ctexture->m_depthBindCount)
|
||||
{
|
||||
if (ctexture == m_boundTarget.get())
|
||||
SetImageLayout(cmdBuf, ctexture->m_depthTex, VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1, 1);
|
||||
if (ctexture->m_samplesDepth <= 1)
|
||||
{
|
||||
VkImageCopy copyInfo = {};
|
||||
SWindowRect intersectRect = rect.intersect(SWindowRect(0, 0, ctexture->m_width, ctexture->m_height));
|
||||
copyInfo.srcOffset.y = tlOrigin ? intersectRect.location[1] :
|
||||
(ctexture->m_height - intersectRect.size[1] - intersectRect.location[1]);
|
||||
copyInfo.srcOffset.x = intersectRect.location[0];
|
||||
copyInfo.dstOffset = copyInfo.srcOffset;
|
||||
copyInfo.extent.width = intersectRect.size[0];
|
||||
copyInfo.extent.height = intersectRect.size[1];
|
||||
copyInfo.extent.depth = 1;
|
||||
copyInfo.dstSubresource.mipLevel = 0;
|
||||
copyInfo.dstSubresource.baseArrayLayer = 0;
|
||||
copyInfo.dstSubresource.layerCount = 1;
|
||||
copyInfo.srcSubresource.mipLevel = 0;
|
||||
copyInfo.srcSubresource.baseArrayLayer = 0;
|
||||
copyInfo.srcSubresource.layerCount = 1;
|
||||
|
||||
SetImageLayout(cmdBuf, ctexture->m_depthBindTex[bindIdx], VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||
ctexture->m_depthBindLayout[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 1);
|
||||
if (ctexture == m_boundTarget.get())
|
||||
SetImageLayout(cmdBuf, ctexture->m_depthTex, VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1, 1);
|
||||
|
||||
copyInfo.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
copyInfo.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
SetImageLayout(cmdBuf, ctexture->m_depthBindTex[bindIdx], VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||
ctexture->m_depthBindLayout[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 1);
|
||||
|
||||
vk::CmdCopyImage(cmdBuf,
|
||||
ctexture->m_depthTex, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
ctexture->m_depthBindTex[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
1, ©Info);
|
||||
copyInfo.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
copyInfo.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
|
||||
if (ctexture == m_boundTarget.get())
|
||||
SetImageLayout(cmdBuf, ctexture->m_depthTex, VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, 1);
|
||||
vk::CmdCopyImage(cmdBuf,
|
||||
ctexture->m_depthTex, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
ctexture->m_depthBindTex[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
1, ©Info);
|
||||
|
||||
SetImageLayout(cmdBuf, ctexture->m_depthBindTex[bindIdx], VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1, 1);
|
||||
ctexture->m_depthBindLayout[bindIdx] = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
if (ctexture == m_boundTarget.get())
|
||||
SetImageLayout(cmdBuf, ctexture->m_depthTex, VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, 1);
|
||||
|
||||
SetImageLayout(cmdBuf, ctexture->m_depthBindTex[bindIdx], VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1, 1);
|
||||
ctexture->m_depthBindLayout[bindIdx] = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
VkImageResolve resolveInfo = {};
|
||||
SWindowRect intersectRect = rect.intersect(SWindowRect(0, 0, ctexture->m_width, ctexture->m_height));
|
||||
resolveInfo.srcOffset.y = tlOrigin ? intersectRect.location[1] :
|
||||
(ctexture->m_height - intersectRect.size[1] - intersectRect.location[1]);
|
||||
resolveInfo.srcOffset.x = intersectRect.location[0];
|
||||
resolveInfo.dstOffset = resolveInfo.srcOffset;
|
||||
resolveInfo.extent.width = intersectRect.size[0];
|
||||
resolveInfo.extent.height = intersectRect.size[1];
|
||||
resolveInfo.extent.depth = 1;
|
||||
resolveInfo.dstSubresource.mipLevel = 0;
|
||||
resolveInfo.dstSubresource.baseArrayLayer = 0;
|
||||
resolveInfo.dstSubresource.layerCount = 1;
|
||||
resolveInfo.srcSubresource.mipLevel = 0;
|
||||
resolveInfo.srcSubresource.baseArrayLayer = 0;
|
||||
resolveInfo.srcSubresource.layerCount = 1;
|
||||
|
||||
if (ctexture == m_boundTarget.get())
|
||||
SetImageLayout(cmdBuf, ctexture->m_depthTex, VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1, 1);
|
||||
|
||||
SetImageLayout(cmdBuf, ctexture->m_depthBindTex[bindIdx], VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||
ctexture->m_depthBindLayout[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 1);
|
||||
|
||||
resolveInfo.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
resolveInfo.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
|
||||
vk::CmdResolveImage(cmdBuf,
|
||||
ctexture->m_depthTex, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
ctexture->m_depthBindTex[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
1, &resolveInfo);
|
||||
|
||||
if (ctexture == m_boundTarget.get())
|
||||
SetImageLayout(cmdBuf, ctexture->m_depthTex, VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, 1);
|
||||
|
||||
SetImageLayout(cmdBuf, ctexture->m_depthBindTex[bindIdx], VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1, 1);
|
||||
ctexture->m_depthBindLayout[bindIdx] = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
}
|
||||
}
|
||||
|
||||
vk::CmdBeginRenderPass(cmdBuf, &m_boundTarget.cast<VulkanTextureR>()->m_passBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
@ -3083,9 +3227,8 @@ void VulkanTextureD::unmap()
|
|||
m_validSlots = 0;
|
||||
}
|
||||
|
||||
VulkanDataFactoryImpl::VulkanDataFactoryImpl(IGraphicsContext* parent,
|
||||
VulkanContext* ctx, uint32_t drawSamples)
|
||||
: m_parent(parent), m_ctx(ctx), m_drawSamples(drawSamples)
|
||||
VulkanDataFactoryImpl::VulkanDataFactoryImpl(IGraphicsContext* parent, VulkanContext* ctx)
|
||||
: m_parent(parent), m_ctx(ctx)
|
||||
{
|
||||
VkDescriptorSetLayoutBinding layoutBindings[BOO_GLSL_MAX_UNIFORM_COUNT + BOO_GLSL_MAX_TEXTURE_COUNT];
|
||||
for (int i=0 ; i<BOO_GLSL_MAX_UNIFORM_COUNT ; ++i)
|
||||
|
@ -3124,7 +3267,7 @@ VulkanDataFactoryImpl::VulkanDataFactoryImpl(IGraphicsContext* parent,
|
|||
|
||||
/* color attachment */
|
||||
attachments[0].format = ctx->m_displayFormat;
|
||||
attachments[0].samples = VkSampleCountFlagBits(drawSamples);
|
||||
attachments[0].samples = VkSampleCountFlagBits(m_ctx->m_sampleCountColor);
|
||||
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
|
@ -3135,7 +3278,7 @@ VulkanDataFactoryImpl::VulkanDataFactoryImpl(IGraphicsContext* parent,
|
|||
|
||||
/* depth attachment */
|
||||
attachments[1].format = VK_FORMAT_D32_SFLOAT;
|
||||
attachments[1].samples = VkSampleCountFlagBits(drawSamples);
|
||||
attachments[1].samples = VkSampleCountFlagBits(m_ctx->m_sampleCountDepth);
|
||||
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
|
@ -3422,7 +3565,7 @@ VulkanDataFactory::Context::newRenderTexture(size_t width, size_t height, Textur
|
|||
{
|
||||
VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent);
|
||||
VulkanCommandQueue* q = static_cast<VulkanCommandQueue*>(factory.m_parent->getCommandQueue());
|
||||
return {new VulkanTextureR(m_data, factory.m_ctx, q, width, height, factory.m_drawSamples,
|
||||
return {new VulkanTextureR(m_data, factory.m_ctx, q, width, height,
|
||||
clampMode, colorBindCount, depthBindCount)};
|
||||
}
|
||||
|
||||
|
@ -3489,6 +3632,8 @@ void VulkanDataFactoryImpl::commitTransaction
|
|||
for (ITextureD& tex : *data->m_DTexs)
|
||||
texMemSize = static_cast<VulkanTextureD&>(tex).sizeForGPU(m_ctx, texMemTypeBits, texMemSize);
|
||||
|
||||
std::unique_lock<std::mutex> qlk(m_ctx->m_queueLock);
|
||||
|
||||
/* allocate memory and place textures */
|
||||
if (bufMemSize)
|
||||
{
|
||||
|
@ -3546,7 +3691,6 @@ void VulkanDataFactoryImpl::commitTransaction
|
|||
submitInfo.pCommandBuffers = &m_ctx->m_loadCmdBuf;
|
||||
|
||||
/* Take exclusive lock here and submit queue */
|
||||
std::unique_lock<std::mutex> qlk(m_ctx->m_queueLock);
|
||||
ThrowIfFailed(vk::QueueWaitIdle(m_ctx->m_queue));
|
||||
ThrowIfFailed(vk::QueueSubmit(m_ctx->m_queue, 1, &submitInfo, VK_NULL_HANDLE));
|
||||
|
||||
|
@ -3751,10 +3895,9 @@ IGraphicsCommandQueue* _NewVulkanCommandQueue(VulkanContext* ctx, VulkanContext:
|
|||
return new struct VulkanCommandQueue(ctx, windowCtx, parent);
|
||||
}
|
||||
|
||||
IGraphicsDataFactory* _NewVulkanDataFactory(IGraphicsContext* parent, VulkanContext* ctx,
|
||||
uint32_t drawSamples)
|
||||
IGraphicsDataFactory* _NewVulkanDataFactory(IGraphicsContext* parent, VulkanContext* ctx)
|
||||
{
|
||||
return new class VulkanDataFactoryImpl(parent, ctx, drawSamples);
|
||||
return new class VulkanDataFactoryImpl(parent, ctx);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -222,6 +222,7 @@ int ApplicationRun(IApplication::EPlatformType platform,
|
|||
SystemStringView friendlyName,
|
||||
SystemStringView pname,
|
||||
const std::vector<SystemString>& args,
|
||||
std::string_view gfxApi,
|
||||
uint32_t samples,
|
||||
uint32_t anisotropy,
|
||||
bool singleInstance)
|
||||
|
|
|
@ -36,8 +36,7 @@ namespace boo
|
|||
{
|
||||
static logvisor::Module Log("boo::ApplicationUWP");
|
||||
|
||||
std::shared_ptr<IWindow> _WindowUWPNew(SystemStringView title, Boo3DAppContextUWP& d3dCtx,
|
||||
uint32_t sampleCount);
|
||||
std::shared_ptr<IWindow> _WindowUWPNew(SystemStringView title, Boo3DAppContextUWP& d3dCtx);
|
||||
|
||||
class ApplicationUWP final : public IApplication
|
||||
{
|
||||
|
@ -260,7 +259,7 @@ public:
|
|||
|
||||
void _setWindow(CoreWindow^ window)
|
||||
{
|
||||
m_window = _WindowUWPNew(m_friendlyName, m_3dCtx, 1);
|
||||
m_window = _WindowUWPNew(m_friendlyName, m_3dCtx);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -67,8 +67,7 @@ namespace boo
|
|||
static logvisor::Module Log("boo::ApplicationWin32");
|
||||
Win32Cursors WIN32_CURSORS;
|
||||
|
||||
std::shared_ptr<IWindow> _WindowWin32New(SystemStringView title, Boo3DAppContextWin32& d3dCtx,
|
||||
uint32_t sampleCount);
|
||||
std::shared_ptr<IWindow> _WindowWin32New(SystemStringView title, Boo3DAppContextWin32& d3dCtx);
|
||||
|
||||
class ApplicationWin32 final : public IApplication
|
||||
{
|
||||
|
@ -97,6 +96,9 @@ public:
|
|||
SystemStringView friendlyName,
|
||||
SystemStringView pname,
|
||||
const std::vector<SystemString>& args,
|
||||
std::string_view gfxApi,
|
||||
uint32_t samples,
|
||||
uint32_t anisotropy,
|
||||
bool singleInstance)
|
||||
: m_callback(callback),
|
||||
m_uniqueName(uniqueName),
|
||||
|
@ -105,6 +107,16 @@ public:
|
|||
m_args(args),
|
||||
m_singleInstance(singleInstance)
|
||||
{
|
||||
m_3dCtx.m_ctx11.m_sampleCount = samples;
|
||||
m_3dCtx.m_ctx11.m_anisotropy = anisotropy;
|
||||
m_3dCtx.m_ctx12.m_sampleCount = samples;
|
||||
m_3dCtx.m_ctx12.m_anisotropy = anisotropy;
|
||||
m_3dCtx.m_ctxOgl.m_glCtx.m_sampleCount = samples;
|
||||
m_3dCtx.m_ctxOgl.m_glCtx.m_anisotropy = anisotropy;
|
||||
g_VulkanContext.m_sampleCountColor = samples;
|
||||
g_VulkanContext.m_sampleCountDepth = samples;
|
||||
g_VulkanContext.m_anisotropy = anisotropy;
|
||||
|
||||
HMODULE dxgilib = LoadLibraryW(L"dxgi.dll");
|
||||
if (!dxgilib)
|
||||
Log.report(logvisor::Fatal, "unable to load dxgi.dll");
|
||||
|
@ -119,6 +131,30 @@ public:
|
|||
#if BOO_HAS_VULKAN
|
||||
bool useVulkan = true;
|
||||
#endif
|
||||
if (!gfxApi.empty())
|
||||
{
|
||||
#if BOO_HAS_VULKAN
|
||||
if (!gfxApi.compare("D3D12"))
|
||||
{
|
||||
useVulkan = false;
|
||||
yes12 = true;
|
||||
}
|
||||
if (!gfxApi.compare("Vulkan"))
|
||||
{
|
||||
noD3d = true;
|
||||
}
|
||||
if (!gfxApi.compare("OpenGL"))
|
||||
{
|
||||
noD3d = true;
|
||||
useVulkan = false;
|
||||
}
|
||||
#else
|
||||
if (!gfxApi.compare(L"D3D12"))
|
||||
yes12 = true;
|
||||
if (!gfxApi.compare(L"OpenGL"))
|
||||
noD3d = true;
|
||||
#endif
|
||||
}
|
||||
for (const SystemString& arg : args)
|
||||
{
|
||||
#if BOO_HAS_VULKAN
|
||||
|
@ -127,9 +163,9 @@ public:
|
|||
useVulkan = false;
|
||||
yes12 = true;
|
||||
}
|
||||
if (!arg.compare(L"--d3d11"))
|
||||
if (!arg.compare(L"--vulkan"))
|
||||
{
|
||||
useVulkan = false;
|
||||
noD3d = true;
|
||||
}
|
||||
if (!arg.compare(L"--gl"))
|
||||
{
|
||||
|
@ -144,40 +180,6 @@ public:
|
|||
#endif
|
||||
}
|
||||
|
||||
#if BOO_HAS_VULKAN
|
||||
if (useVulkan)
|
||||
{
|
||||
HMODULE vulkanLib = LoadLibraryW(L"vulkan-1.dll");
|
||||
if (vulkanLib)
|
||||
{
|
||||
m_getVkProc = (PFN_vkGetInstanceProcAddr)GetProcAddress(vulkanLib, "vkGetInstanceProcAddr");
|
||||
if (m_getVkProc)
|
||||
{
|
||||
/* Check device support for vulkan */
|
||||
vk::init_dispatch_table_top(PFN_vkGetInstanceProcAddr(m_getVkProc));
|
||||
if (g_VulkanContext.m_instance == VK_NULL_HANDLE)
|
||||
{
|
||||
auto appName = getUniqueName();
|
||||
if (g_VulkanContext.initVulkan(WCSTMBS(appName.data()).c_str()))
|
||||
{
|
||||
vk::init_dispatch_table_middle(g_VulkanContext.m_instance, false);
|
||||
if (g_VulkanContext.enumerateDevices())
|
||||
{
|
||||
/* Obtain DXGI Factory */
|
||||
HRESULT hr = MyCreateDXGIFactory1(__uuidof(IDXGIFactory1), &m_3dCtx.m_vulkanDxFactory);
|
||||
if (FAILED(hr))
|
||||
Log.report(logvisor::Fatal, "unable to create DXGI factory");
|
||||
|
||||
Log.report(logvisor::Info, "initialized Vulkan renderer");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if _WIN32_WINNT_WIN10
|
||||
HMODULE d3d12lib = nullptr;
|
||||
if (yes12 && !noD3d)
|
||||
|
@ -303,11 +305,15 @@ public:
|
|||
device->GetParent(__uuidof(IDXGIAdapter), &adapter);
|
||||
adapter->GetParent(__uuidof(IDXGIFactory2), &m_3dCtx.m_ctx11.m_dxFactory);
|
||||
|
||||
m_3dCtx.m_ctx11.m_anisotropy = std::min(m_3dCtx.m_ctx11.m_anisotropy, uint32_t(16));
|
||||
|
||||
/* Build default sampler here */
|
||||
CD3D11_SAMPLER_DESC sampDesc(D3D11_DEFAULT);
|
||||
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
sampDesc.Filter = D3D11_FILTER_ANISOTROPIC;
|
||||
sampDesc.MaxAnisotropy = m_3dCtx.m_ctx11.m_anisotropy;
|
||||
m_3dCtx.m_ctx11.m_dev->CreateSamplerState(&sampDesc, &m_3dCtx.m_ctx11.m_ss[0]);
|
||||
|
||||
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
|
@ -324,6 +330,40 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
#if BOO_HAS_VULKAN
|
||||
if (useVulkan)
|
||||
{
|
||||
HMODULE vulkanLib = LoadLibraryW(L"vulkan-1.dll");
|
||||
if (vulkanLib)
|
||||
{
|
||||
m_getVkProc = (PFN_vkGetInstanceProcAddr)GetProcAddress(vulkanLib, "vkGetInstanceProcAddr");
|
||||
if (m_getVkProc)
|
||||
{
|
||||
/* Check device support for vulkan */
|
||||
vk::init_dispatch_table_top(PFN_vkGetInstanceProcAddr(m_getVkProc));
|
||||
if (g_VulkanContext.m_instance == VK_NULL_HANDLE)
|
||||
{
|
||||
auto appName = getUniqueName();
|
||||
if (g_VulkanContext.initVulkan(WCSTMBS(appName.data()).c_str()))
|
||||
{
|
||||
vk::init_dispatch_table_middle(g_VulkanContext.m_instance, false);
|
||||
if (g_VulkanContext.enumerateDevices())
|
||||
{
|
||||
/* Obtain DXGI Factory */
|
||||
HRESULT hr = MyCreateDXGIFactory1(__uuidof(IDXGIFactory1), &m_3dCtx.m_vulkanDxFactory);
|
||||
if (FAILED(hr))
|
||||
Log.report(logvisor::Fatal, "unable to create DXGI factory");
|
||||
|
||||
Log.report(logvisor::Info, "initialized Vulkan renderer");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Finally try OpenGL */
|
||||
{
|
||||
/* Obtain DXGI Factory */
|
||||
|
@ -425,7 +465,7 @@ public:
|
|||
/* New-window message (coalesced onto main thread) */
|
||||
std::unique_lock<std::mutex> lk(m_nwmt);
|
||||
SystemStringView* title = reinterpret_cast<SystemStringView*>(msg.wParam);
|
||||
m_mwret = newWindow(*title, 1);
|
||||
m_mwret = newWindow(*title);
|
||||
lk.unlock();
|
||||
m_nwcv.notify_one();
|
||||
continue;
|
||||
|
@ -481,7 +521,7 @@ public:
|
|||
std::mutex m_nwmt;
|
||||
std::condition_variable m_nwcv;
|
||||
std::shared_ptr<IWindow> m_mwret;
|
||||
std::shared_ptr<IWindow> newWindow(SystemStringView title, uint32_t sampleCount)
|
||||
std::shared_ptr<IWindow> newWindow(SystemStringView title)
|
||||
{
|
||||
if (GetCurrentThreadId() != g_mainThreadId)
|
||||
{
|
||||
|
@ -494,7 +534,7 @@ public:
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::shared_ptr<IWindow> window = _WindowWin32New(title, m_3dCtx, sampleCount);
|
||||
std::shared_ptr<IWindow> window = _WindowWin32New(title, m_3dCtx);
|
||||
HWND hwnd = HWND(window->getPlatformHandle());
|
||||
m_allWindows[hwnd] = window;
|
||||
return window;
|
||||
|
@ -508,6 +548,9 @@ int ApplicationRun(IApplication::EPlatformType platform,
|
|||
SystemStringView friendlyName,
|
||||
SystemStringView pname,
|
||||
const std::vector<SystemString>& args,
|
||||
std::string_view gfxApi,
|
||||
uint32_t samples,
|
||||
uint32_t anisotropy,
|
||||
bool singleInstance)
|
||||
{
|
||||
std::string thrName = WCSTMBS(friendlyName.data()) + " Main Thread";
|
||||
|
@ -522,15 +565,8 @@ int ApplicationRun(IApplication::EPlatformType platform,
|
|||
/* HI-DPI support */
|
||||
HMODULE shcoreLib = LoadLibraryW(L"Shcore.dll");
|
||||
if (shcoreLib)
|
||||
{
|
||||
PFN_SetProcessDpiAwareness MySetProcessDpiAwareness =
|
||||
(PFN_SetProcessDpiAwareness)GetProcAddress(shcoreLib, "SetProcessDpiAwareness");
|
||||
if (MySetProcessDpiAwareness)
|
||||
MySetProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE);
|
||||
|
||||
MyGetScaleFactorForMonitor =
|
||||
(PFN_GetScaleFactorForMonitor)GetProcAddress(shcoreLib, "GetScaleFactorForMonitor");
|
||||
}
|
||||
#endif
|
||||
|
||||
WIN32_CURSORS.m_arrow = LoadCursor(nullptr, IDC_ARROW);
|
||||
|
@ -558,7 +594,8 @@ int ApplicationRun(IApplication::EPlatformType platform,
|
|||
wndClass.hCursor = WIN32_CURSORS.m_arrow;
|
||||
ATOM a = RegisterClassW(&wndClass);
|
||||
|
||||
APP = new ApplicationWin32(cb, uniqueName, friendlyName, pname, args, singleInstance);
|
||||
APP = new ApplicationWin32(cb, uniqueName, friendlyName, pname, args,
|
||||
gfxApi, samples, anisotropy, singleInstance);
|
||||
return APP->run();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
#if BOO_HAS_VULKAN
|
||||
#include "boo/graphicsdev/Vulkan.hpp"
|
||||
#endif
|
||||
#include "boo/graphicsdev/GL.hpp"
|
||||
|
||||
extern DWORD g_mainThreadId;
|
||||
|
||||
#if _WIN32_WINNT_WINBLUE && !WINDOWS_STORE
|
||||
#include <ShellScalingApi.h>
|
||||
typedef HRESULT (WINAPI* PFN_SetProcessDpiAwareness)( _In_ PROCESS_DPI_AWARENESS );
|
||||
typedef HRESULT (WINAPI* PFN_GetScaleFactorForMonitor)( _In_ HMONITOR, _Out_ DEVICE_SCALE_FACTOR *);
|
||||
extern PFN_GetScaleFactorForMonitor MyGetScaleFactorForMonitor;
|
||||
#endif
|
||||
|
@ -43,6 +43,8 @@ struct OGLContext
|
|||
int m_fsCountDown = 0;
|
||||
};
|
||||
std::unordered_map<const boo::IWindow*, Window> m_windows;
|
||||
|
||||
boo::GLContext m_glCtx;
|
||||
};
|
||||
|
||||
template <class W>
|
||||
|
|
|
@ -44,6 +44,9 @@ struct D3D12Context
|
|||
size_t width, height;
|
||||
};
|
||||
std::unordered_map<const boo::IWindow*, Window> m_windows;
|
||||
|
||||
uint32_t m_sampleCount = 1;
|
||||
uint32_t m_anisotropy = 1;
|
||||
};
|
||||
|
||||
struct D3D11Context
|
||||
|
@ -63,6 +66,9 @@ struct D3D11Context
|
|||
DXGI_MODE_DESC m_fsdesc = {};
|
||||
};
|
||||
std::unordered_map<const boo::IWindow*, Window> m_windows;
|
||||
|
||||
uint32_t m_sampleCount = 1;
|
||||
uint32_t m_anisotropy = 1;
|
||||
};
|
||||
|
||||
struct Boo3DAppContext
|
||||
|
|
|
@ -58,7 +58,7 @@ public:
|
|||
IWindowCallback* m_callback;
|
||||
|
||||
GraphicsContextUWPD3D(EGraphicsAPI api, IWindow* parentWindow, Agile<CoreWindow>& coreWindow,
|
||||
Boo3DAppContextUWP& b3dCtx, uint32_t sampleCount)
|
||||
Boo3DAppContextUWP& b3dCtx)
|
||||
: GraphicsContextUWP(api, parentWindow, b3dCtx)
|
||||
{
|
||||
/* Create Swap Chain */
|
||||
|
@ -83,7 +83,7 @@ public:
|
|||
D3D12Context::Window& w = insIt.first->second;
|
||||
|
||||
ID3D12CommandQueue* cmdQueue;
|
||||
m_dataFactory = _NewD3D12DataFactory(&b3dCtx.m_ctx12, this, sampleCount);
|
||||
m_dataFactory = _NewD3D12DataFactory(&b3dCtx.m_ctx12, this);
|
||||
m_commandQueue = _NewD3D12CommandQueue(&b3dCtx.m_ctx12, &w, this, &cmdQueue);
|
||||
|
||||
scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
|
@ -120,7 +120,7 @@ public:
|
|||
fbRes->GetDesc(&resDesc);
|
||||
w.width = resDesc.Width;
|
||||
w.height = resDesc.Height;
|
||||
m_dataFactory = _NewD3D11DataFactory(&b3dCtx.m_ctx11, this, sampleCount);
|
||||
m_dataFactory = _NewD3D11DataFactory(&b3dCtx.m_ctx11, this);
|
||||
m_commandQueue = _NewD3D11CommandQueue(&b3dCtx.m_ctx11, &insIt.first->second, this);
|
||||
|
||||
if (FAILED(m_swapChain->GetContainingOutput(&m_output)))
|
||||
|
@ -337,7 +337,7 @@ public:
|
|||
};
|
||||
EventReceiver^ m_eventReceiver;
|
||||
|
||||
WindowUWP(SystemStringView title, Boo3DAppContextUWP& b3dCtx, uint32_t sampleCount)
|
||||
WindowUWP(SystemStringView title, Boo3DAppContextUWP& b3dCtx)
|
||||
: m_coreWindow(CoreWindow::GetForCurrentThread()),
|
||||
m_eventReceiver(ref new EventReceiver(*this))
|
||||
{
|
||||
|
@ -346,7 +346,7 @@ public:
|
|||
if (b3dCtx.m_ctx12.m_dev)
|
||||
api = IGraphicsContext::EGraphicsAPI::D3D12;
|
||||
#endif
|
||||
m_gfxCtx.reset(new GraphicsContextUWPD3D(api, this, m_coreWindow, b3dCtx, sampleCount));
|
||||
m_gfxCtx.reset(new GraphicsContextUWPD3D(api, this, m_coreWindow, b3dCtx));
|
||||
|
||||
setTitle(title);
|
||||
m_bounds = m_coreWindow->Bounds;
|
||||
|
@ -628,10 +628,9 @@ public:
|
|||
|
||||
};
|
||||
|
||||
std::shared_ptr<IWindow> _WindowUWPNew(SystemStringView title, Boo3DAppContextUWP& d3dCtx,
|
||||
uint32_t sampleCount)
|
||||
std::shared_ptr<IWindow> _WindowUWPNew(SystemStringView title, Boo3DAppContextUWP& d3dCtx)
|
||||
{
|
||||
return std::make_shared<WindowUWP>(title, d3dCtx, sampleCount);
|
||||
return std::make_shared<WindowUWP>(title, d3dCtx);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,18 +31,17 @@ static logvisor::Module Log("boo::WindowWin32");
|
|||
#if _WIN32_WINNT_WIN10
|
||||
IGraphicsCommandQueue* _NewD3D12CommandQueue(D3D12Context* ctx, D3D12Context::Window* windowCtx, IGraphicsContext* parent,
|
||||
ID3D12CommandQueue** cmdQueueOut);
|
||||
IGraphicsDataFactory* _NewD3D12DataFactory(D3D12Context* ctx, IGraphicsContext* parent, uint32_t sampleCount);
|
||||
IGraphicsDataFactory* _NewD3D12DataFactory(D3D12Context* ctx, IGraphicsContext* parent);
|
||||
#endif
|
||||
IGraphicsCommandQueue* _NewD3D11CommandQueue(D3D11Context* ctx, D3D11Context::Window* windowCtx, IGraphicsContext* parent);
|
||||
IGraphicsDataFactory* _NewD3D11DataFactory(D3D11Context* ctx, IGraphicsContext* parent, uint32_t sampleCount);
|
||||
IGraphicsDataFactory* _NewD3D11DataFactory(D3D11Context* ctx, IGraphicsContext* parent);
|
||||
IGraphicsCommandQueue* _NewGLCommandQueue(IGraphicsContext* parent, GLContext* glCtx);
|
||||
IGraphicsDataFactory* _NewGLDataFactory(IGraphicsContext* parent, GLContext* glCtx);
|
||||
#if BOO_HAS_VULKAN
|
||||
IGraphicsCommandQueue* _NewVulkanCommandQueue(VulkanContext* ctx,
|
||||
VulkanContext::Window* windowCtx,
|
||||
IGraphicsContext* parent);
|
||||
IGraphicsDataFactory* _NewVulkanDataFactory(IGraphicsContext* parent, VulkanContext* ctx,
|
||||
uint32_t drawSamples);
|
||||
IGraphicsDataFactory* _NewVulkanDataFactory(IGraphicsContext* parent, VulkanContext* ctx);
|
||||
#endif
|
||||
|
||||
struct GraphicsContextWin32 : IGraphicsContext
|
||||
|
@ -75,7 +74,7 @@ public:
|
|||
IWindowCallback* m_callback;
|
||||
|
||||
GraphicsContextWin32D3D(EGraphicsAPI api, IWindow* parentWindow, HWND hwnd,
|
||||
Boo3DAppContextWin32& b3dCtx, uint32_t sampleCount)
|
||||
Boo3DAppContextWin32& b3dCtx)
|
||||
: GraphicsContextWin32(api, parentWindow, b3dCtx)
|
||||
{
|
||||
/* Create Swap Chain */
|
||||
|
@ -94,7 +93,7 @@ public:
|
|||
D3D12Context::Window& w = insIt.first->second;
|
||||
|
||||
ID3D12CommandQueue* cmdQueue;
|
||||
m_dataFactory = _NewD3D12DataFactory(&b3dCtx.m_ctx12, this, sampleCount);
|
||||
m_dataFactory = _NewD3D12DataFactory(&b3dCtx.m_ctx12, this);
|
||||
m_commandQueue = _NewD3D12CommandQueue(&b3dCtx.m_ctx12, &w, this, &cmdQueue);
|
||||
|
||||
scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
|
@ -133,7 +132,7 @@ public:
|
|||
fbRes->GetDesc(&resDesc);
|
||||
w.width = resDesc.Width;
|
||||
w.height = resDesc.Height;
|
||||
m_dataFactory = _NewD3D11DataFactory(&b3dCtx.m_ctx11, this, sampleCount);
|
||||
m_dataFactory = _NewD3D11DataFactory(&b3dCtx.m_ctx11, this);
|
||||
m_commandQueue = _NewD3D11CommandQueue(&b3dCtx.m_ctx11, &insIt.first->second, this);
|
||||
|
||||
if (FAILED(m_swapChain->GetContainingOutput(&m_output)))
|
||||
|
@ -211,7 +210,7 @@ public:
|
|||
IWindowCallback* m_callback;
|
||||
|
||||
GraphicsContextWin32GL(EGraphicsAPI api, IWindow* parentWindow, HWND hwnd,
|
||||
Boo3DAppContextWin32& b3dCtx, uint32_t sampleCount)
|
||||
Boo3DAppContextWin32& b3dCtx)
|
||||
: GraphicsContextWin32(api, parentWindow, b3dCtx)
|
||||
{
|
||||
|
||||
|
@ -283,8 +282,8 @@ public:
|
|||
Log.report(logvisor::Fatal, "unable to share contexts");
|
||||
m_3dCtx.m_ctxOgl.m_lastContext = w.m_mainContext;
|
||||
|
||||
m_dataFactory = _NewGLDataFactory(this, sampleCount);
|
||||
m_commandQueue = _NewGLCommandQueue(this);
|
||||
m_dataFactory = _NewGLDataFactory(this, &b3dCtx.m_ctxOgl.m_glCtx);
|
||||
m_commandQueue = _NewGLCommandQueue(this, &b3dCtx.m_ctxOgl.m_glCtx);
|
||||
}
|
||||
|
||||
~GraphicsContextWin32GL()
|
||||
|
@ -398,7 +397,6 @@ struct GraphicsContextWin32Vulkan : GraphicsContextWin32
|
|||
VkSurfaceKHR m_surface = VK_NULL_HANDLE;
|
||||
VkFormat m_format = VK_FORMAT_UNDEFINED;
|
||||
VkColorSpaceKHR m_colorspace;
|
||||
uint32_t m_sampleCount;
|
||||
|
||||
IGraphicsCommandQueue* m_commandQueue = nullptr;
|
||||
IGraphicsDataFactory* m_dataFactory = nullptr;
|
||||
|
@ -416,9 +414,9 @@ public:
|
|||
IWindowCallback* m_callback;
|
||||
|
||||
GraphicsContextWin32Vulkan(IWindow* parentWindow, HINSTANCE appInstance, HWND hwnd,
|
||||
VulkanContext* ctx, Boo3DAppContextWin32& b3dCtx, uint32_t drawSamples)
|
||||
VulkanContext* ctx, Boo3DAppContextWin32& b3dCtx)
|
||||
: GraphicsContextWin32(EGraphicsAPI::Vulkan, parentWindow, b3dCtx),
|
||||
m_appInstance(appInstance), m_hwnd(hwnd), m_ctx(ctx), m_sampleCount(drawSamples)
|
||||
m_appInstance(appInstance), m_hwnd(hwnd), m_ctx(ctx)
|
||||
{
|
||||
HMONITOR testMon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY);
|
||||
ComPtr<IDXGIAdapter1> adapter;
|
||||
|
@ -586,7 +584,7 @@ public:
|
|||
|
||||
m_ctx->initSwapChain(*m_windowCtx, m_surface, m_format, m_colorspace);
|
||||
|
||||
m_dataFactory = _NewVulkanDataFactory(this, m_ctx, m_sampleCount);
|
||||
m_dataFactory = _NewVulkanDataFactory(this, m_ctx);
|
||||
m_commandQueue = _NewVulkanCommandQueue(m_ctx, m_ctx->m_windows[m_parentWindow].get(), this);
|
||||
return true;
|
||||
}
|
||||
|
@ -960,7 +958,7 @@ class WindowWin32 : public IWindow
|
|||
|
||||
public:
|
||||
|
||||
WindowWin32(SystemStringView title, Boo3DAppContextWin32& b3dCtx, uint32_t sampleCount)
|
||||
WindowWin32(SystemStringView title, Boo3DAppContextWin32& b3dCtx)
|
||||
{
|
||||
m_hwnd = CreateWindowW(L"BooWindow", title.data(), WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
|
@ -971,8 +969,7 @@ public:
|
|||
#if BOO_HAS_VULKAN
|
||||
if (b3dCtx.m_vulkanDxFactory)
|
||||
{
|
||||
m_gfxCtx.reset(new GraphicsContextWin32Vulkan(this, wndInstance, m_hwnd, &g_VulkanContext,
|
||||
b3dCtx, sampleCount));
|
||||
m_gfxCtx.reset(new GraphicsContextWin32Vulkan(this, wndInstance, m_hwnd, &g_VulkanContext, b3dCtx));
|
||||
if (m_gfxCtx->initializeContext(nullptr))
|
||||
return;
|
||||
}
|
||||
|
@ -985,11 +982,11 @@ public:
|
|||
if (b3dCtx.m_ctxOgl.m_dxFactory)
|
||||
{
|
||||
m_gfxCtx.reset(new GraphicsContextWin32GL(IGraphicsContext::EGraphicsAPI::OpenGL3_3,
|
||||
this, m_hwnd, b3dCtx, sampleCount));
|
||||
this, m_hwnd, b3dCtx));
|
||||
m_openGL = true;
|
||||
return;
|
||||
}
|
||||
m_gfxCtx.reset(new GraphicsContextWin32D3D(api, this, m_hwnd, b3dCtx, sampleCount));
|
||||
m_gfxCtx.reset(new GraphicsContextWin32D3D(api, this, m_hwnd, b3dCtx));
|
||||
}
|
||||
|
||||
~WindowWin32()
|
||||
|
@ -1573,10 +1570,9 @@ public:
|
|||
|
||||
};
|
||||
|
||||
std::shared_ptr<IWindow> _WindowWin32New(SystemStringView title, Boo3DAppContextWin32& d3dCtx,
|
||||
uint32_t sampleCount)
|
||||
std::shared_ptr<IWindow> _WindowWin32New(SystemStringView title, Boo3DAppContextWin32& d3dCtx)
|
||||
{
|
||||
return std::make_shared<WindowWin32>(title, d3dCtx, sampleCount);
|
||||
return std::make_shared<WindowWin32>(title, d3dCtx);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ int ApplicationRun(IApplication::EPlatformType platform,
|
|||
std::string_view friendlyName,
|
||||
std::string_view pname,
|
||||
const std::vector<std::string>& args,
|
||||
std::string_view gfxApi,
|
||||
uint32_t samples,
|
||||
uint32_t anisotropy,
|
||||
bool singleInstance)
|
||||
|
|
2
logvisor
2
logvisor
|
@ -1 +1 @@
|
|||
Subproject commit beee8b397056efcdc33020a26cf69d1039f0f802
|
||||
Subproject commit f28fa0dbb2e59d02eb659542b28b13f8d1bfe4fb
|
Loading…
Reference in New Issue