MSAA and Anisotropic filtering variables

This commit is contained in:
Jack Andersen 2018-01-09 20:15:18 -10:00
parent 872ab3900d
commit 4257fc0b10
14 changed files with 446 additions and 224 deletions

View File

@ -61,6 +61,7 @@ ApplicationRun(IApplication::EPlatformType platform,
SystemStringView friendlyName, SystemStringView friendlyName,
SystemStringView pname, SystemStringView pname,
const std::vector<SystemString>& args, const std::vector<SystemString>& args,
std::string_view gfxApi = {},
uint32_t samples = 1, uint32_t samples = 1,
uint32_t anisotropy = 1, uint32_t anisotropy = 1,
bool singleInstance=true); bool singleInstance=true);
@ -72,6 +73,7 @@ ApplicationRun(IApplication::EPlatformType platform,
SystemStringView uniqueName, SystemStringView uniqueName,
SystemStringView friendlyName, SystemStringView friendlyName,
int argc, const SystemChar** argv, int argc, const SystemChar** argv,
std::string_view gfxApi = {},
uint32_t samples = 1, uint32_t samples = 1,
uint32_t anisotropy = 1, uint32_t anisotropy = 1,
bool singleInstance=true) bool singleInstance=true)
@ -82,7 +84,7 @@ ApplicationRun(IApplication::EPlatformType platform,
for (int i=1 ; i<argc ; ++i) for (int i=1 ; i<argc ; ++i)
args.push_back(argv[i]); args.push_back(argv[i]);
return ApplicationRun(platform, cb, uniqueName, friendlyName, argv[0], args, return ApplicationRun(platform, cb, uniqueName, friendlyName, argv[0], args,
samples, anisotropy, singleInstance); gfxApi, samples, anisotropy, singleInstance);
} }
} }

View File

@ -45,7 +45,6 @@ struct VulkanContext
VkRenderPass m_pass; VkRenderPass m_pass;
VkCommandPool m_loadPool; VkCommandPool m_loadPool;
VkCommandBuffer m_loadCmdBuf; VkCommandBuffer m_loadCmdBuf;
VkSampler m_linearSamplers[3];
VkFormat m_displayFormat; VkFormat m_displayFormat;
struct Window struct Window
@ -85,6 +84,12 @@ struct VulkanContext
}; };
std::unordered_map<const boo::IWindow*, std::unique_ptr<Window>> m_windows; 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 initVulkan(std::string_view appName);
bool enumerateDevices(); bool enumerateDevices();
void initDevice(); void initDevice();

View File

@ -158,6 +158,8 @@ class D3D11TextureS : public GraphicsDataNode<ITextureS>
upData[i].pSysMem = dataIt; upData[i].pSysMem = dataIt;
upData[i].SysMemPitch = width * pxPitchNum / pxPitchDenom; upData[i].SysMemPitch = width * pxPitchNum / pxPitchDenom;
upData[i].SysMemSlicePitch = upData[i].SysMemPitch * height; upData[i].SysMemSlicePitch = upData[i].SysMemPitch * height;
if (compressed)
upData[i].SysMemPitch = width * 2;
dataIt += upData[i].SysMemSlicePitch; dataIt += upData[i].SysMemSlicePitch;
if (width > 1) if (width > 1)
width /= 2; width /= 2;
@ -1119,7 +1121,8 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
{ {
if (tex->m_samples > 1) 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 else
{ {
@ -1133,7 +1136,15 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
} }
if (depth && tex->m_depthBindCount) 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) if (clearDepth)
@ -1230,12 +1241,16 @@ class D3D11DataFactory : public ID3DDataFactory, public GraphicsDataFactoryHead
struct D3D11Context* m_ctx; struct D3D11Context* m_ctx;
std::unordered_map<uint64_t, std::unique_ptr<D3D11ShareableShader>> m_sharedShaders; std::unordered_map<uint64_t, std::unique_ptr<D3D11ShareableShader>> m_sharedShaders;
std::unordered_map<uint64_t, uint64_t> m_sourceToBinary; std::unordered_map<uint64_t, uint64_t> m_sourceToBinary;
uint32_t m_sampleCount;
public: public:
D3D11DataFactory(IGraphicsContext* parent, D3D11Context* ctx, uint32_t sampleCount) D3D11DataFactory(IGraphicsContext* parent, D3D11Context* ctx)
: m_parent(parent), m_ctx(ctx), m_sampleCount(sampleCount) : 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;} Platform platform() const {return Platform::D3D11;}
const SystemChar* platformName() const {return _S("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, boo::ObjToken<ITextureR> newRenderTexture(size_t width, size_t height, TextureClampMode clampMode,
size_t colorBindCount, size_t depthBindCount) 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)}; colorBindCount, depthBindCount)};
} }
@ -1293,7 +1308,7 @@ public:
return {new struct D3D11VertexFormat(m_data, elementCount, elements)}; return {new struct D3D11VertexFormat(m_data, elementCount, elements)};
} }
#if _DEBUG #if _DEBUG && 0
#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_DEBUG | D3DCOMPILE_OPTIMIZATION_LEVEL0 #define BOO_D3DCOMPILE_FLAG D3DCOMPILE_DEBUG | D3DCOMPILE_OPTIMIZATION_LEVEL0
#else #else
#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_OPTIMIZATION_LEVEL3 #define BOO_D3DCOMPILE_FLAG D3DCOMPILE_OPTIMIZATION_LEVEL3
@ -1546,9 +1561,9 @@ IGraphicsCommandQueue* _NewD3D11CommandQueue(D3D11Context* ctx, D3D11Context::Wi
return new D3D11CommandQueue(ctx, windowCtx, parent); 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);
} }
} }

View File

@ -228,6 +228,8 @@ class D3D12TextureS : public GraphicsDataNode<ITextureS>
upData[i].pData = dataIt; upData[i].pData = dataIt;
upData[i].RowPitch = width * pxPitchNum / pxPitchDenom; upData[i].RowPitch = width * pxPitchNum / pxPitchDenom;
upData[i].SlicePitch = upData[i].RowPitch * height; upData[i].SlicePitch = upData[i].RowPitch * height;
if (compressed)
upData[i].RowPitch = width * 2;
dataIt += upData[i].SlicePitch; dataIt += upData[i].SlicePitch;
if (width > 1) if (width > 1)
width /= 2; width /= 2;
@ -446,9 +448,11 @@ class D3D12TextureR : public GraphicsDataNode<ITextureR>
rtvDim = D3D12_RTV_DIMENSION_TEXTURE2DMS; rtvDim = D3D12_RTV_DIMENSION_TEXTURE2DMS;
dsvDim = D3D12_DSV_DIMENSION_TEXTURE2DMS; dsvDim = D3D12_DSV_DIMENSION_TEXTURE2DMS;
rtvresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, m_width, m_height, 1, 1, m_samples, 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, 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 else
{ {
@ -744,7 +748,8 @@ class D3D12ShaderPipeline : public GraphicsDataNode<IShaderPipeline>
desc.NumRenderTargets = 1; desc.NumRenderTargets = 1;
desc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; desc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT; 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) if (pipeline)
{ {
desc.CachedPSO.pCachedBlob = pipeline->GetBufferPointer(); desc.CachedPSO.pCachedBlob = pipeline->GetBufferPointer();
@ -1670,12 +1675,22 @@ class D3D12DataFactory : public ID3DDataFactory, public GraphicsDataFactoryHead
struct D3D12Context* m_ctx; struct D3D12Context* m_ctx;
std::unordered_map<uint64_t, std::unique_ptr<D3D12ShareableShader>> m_sharedShaders; std::unordered_map<uint64_t, std::unique_ptr<D3D12ShareableShader>> m_sharedShaders;
std::unordered_map<uint64_t, uint64_t> m_sourceToBinary; std::unordered_map<uint64_t, uint64_t> m_sourceToBinary;
uint32_t m_sampleCount;
public: public:
D3D12DataFactory(IGraphicsContext* parent, D3D12Context* ctx, uint32_t sampleCount) D3D12DataFactory(IGraphicsContext* parent, D3D12Context* ctx)
: m_parent(parent), m_ctx(ctx), m_sampleCount(sampleCount) : 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[] = CD3DX12_DESCRIPTOR_RANGE ranges[] =
{ {
{D3D12_DESCRIPTOR_RANGE_TYPE_CBV, MAX_UNIFORM_COUNT, 0}, {D3D12_DESCRIPTOR_RANGE_TYPE_CBV, MAX_UNIFORM_COUNT, 0},
@ -1689,11 +1704,12 @@ public:
D3D12_STATIC_SAMPLER_DESC samplers[] = 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, 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, 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( ThrowIfFailed(D3D12SerializeRootSignaturePROC(
@ -1758,7 +1774,7 @@ public:
size_t colorBindCount, size_t depthBindCount) size_t colorBindCount, size_t depthBindCount)
{ {
D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent.m_parent->getCommandQueue()); 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)}; colorBindCount, depthBindCount)};
} }
@ -1769,7 +1785,7 @@ public:
return {new struct D3D12VertexFormat(m_data, elementCount, elements)}; return {new struct D3D12VertexFormat(m_data, elementCount, elements)};
} }
#if _DEBUG #if _DEBUG && 0
#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_DEBUG | D3DCOMPILE_OPTIMIZATION_LEVEL0 #define BOO_D3DCOMPILE_FLAG D3DCOMPILE_DEBUG | D3DCOMPILE_OPTIMIZATION_LEVEL0
#else #else
#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_OPTIMIZATION_LEVEL3 #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); 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);
} }
} }

View File

@ -40,12 +40,11 @@ class VulkanDataFactoryImpl : public VulkanDataFactory, public GraphicsDataFacto
friend struct VulkanPool; friend struct VulkanPool;
IGraphicsContext* m_parent; IGraphicsContext* m_parent;
VulkanContext* m_ctx; VulkanContext* m_ctx;
uint32_t m_drawSamples;
std::unordered_map<uint64_t, std::unique_ptr<VulkanShareableShader>> m_sharedShaders; std::unordered_map<uint64_t, std::unique_ptr<VulkanShareableShader>> m_sharedShaders;
std::vector<int> m_texUnis; std::vector<int> m_texUnis;
public: public:
std::unordered_map<uint64_t, uint64_t> m_sourceToBinary; 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;} Platform platform() const {return Platform::Vulkan;}
const SystemChar* platformName() const {return _S("Vulkan");} const SystemChar* platformName() const {return _S("Vulkan");}
@ -441,6 +440,10 @@ void VulkanContext::initDevice()
VkPhysicalDeviceFeatures features = {}; VkPhysicalDeviceFeatures features = {};
if (m_features.samplerAnisotropy) if (m_features.samplerAnisotropy)
features.samplerAnisotropy = VK_TRUE; 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 = {}; VkDeviceCreateInfo deviceInfo = {};
deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
@ -469,7 +472,8 @@ void VulkanContext::initDevice()
m_gpuProps.driverVersion & 0b111111111111); 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; m_displayFormat = format;
VkSurfaceCapabilitiesKHR surfCapabilities; VkSurfaceCapabilitiesKHR surfCapabilities;
@ -590,32 +594,13 @@ void VulkanContext::initSwapChain(VulkanContext::Window& windowCtx, VkSurfaceKHR
cmdBufBeginInfo.flags = 0; cmdBufBeginInfo.flags = 0;
ThrowIfFailed(vk::BeginCommandBuffer(m_loadCmdBuf, &cmdBufBeginInfo)); ThrowIfFailed(vk::BeginCommandBuffer(m_loadCmdBuf, &cmdBufBeginInfo));
/* Create shared linear sampler */ m_sampleCountColor = flp2(std::min(m_gpuProps.limits.framebufferColorSampleCounts, m_sampleCountColor));
VkSamplerCreateInfo samplerInfo = {}; m_sampleCountDepth = flp2(std::min(m_gpuProps.limits.framebufferDepthSampleCounts, m_sampleCountDepth));
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]));
/* Create shared white-clamped sampler */ if (m_features.samplerAnisotropy)
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; m_anisotropy = std::min(m_gpuProps.limits.maxSamplerAnisotropy, m_anisotropy);
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; else
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; m_anisotropy = 1;
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]));
/* images */ /* images */
sc.m_bufs.resize(swapchainImageCount); 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> class VulkanTextureS : public GraphicsDataNode<ITextureS>
{ {
friend class VulkanDataFactory; 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; texCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_gpuTex)); 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; m_descInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
} }
public: public:
@ -1030,6 +1059,7 @@ public:
VkDeviceMemory m_cpuMem; VkDeviceMemory m_cpuMem;
VkImage m_gpuTex; VkImage m_gpuTex;
VkImageView m_gpuView = VK_NULL_HANDLE; VkImageView m_gpuView = VK_NULL_HANDLE;
VkSampler m_sampler = VK_NULL_HANDLE;
VkDescriptorImageInfo m_descInfo; VkDescriptorImageInfo m_descInfo;
VkDeviceSize m_gpuOffset; VkDeviceSize m_gpuOffset;
~VulkanTextureS() ~VulkanTextureS()
@ -1044,7 +1074,8 @@ public:
void setClampMode(TextureClampMode mode) 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() void deleteUploadObjects()
@ -1106,7 +1137,7 @@ public:
size_t offset = 0; size_t offset = 0;
for (int i=0 ; i<regionCount ; ++i) 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.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copyRegions[i].imageSubresource.mipLevel = i; copyRegions[i].imageSubresource.mipLevel = i;
@ -1121,7 +1152,7 @@ public:
width /= 2; width /= 2;
if (height > 1) if (height > 1)
height /= 2; height /= 2;
offset += srcRowPitch; offset += regionPitch;
} }
/* Put the copy command into the command buffer */ /* 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; texCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_gpuTex)); 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; m_descInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
} }
public: public:
@ -1232,6 +1263,7 @@ public:
VkDeviceMemory m_cpuMem; VkDeviceMemory m_cpuMem;
VkImage m_gpuTex; VkImage m_gpuTex;
VkImageView m_gpuView = VK_NULL_HANDLE; VkImageView m_gpuView = VK_NULL_HANDLE;
VkSampler m_sampler = VK_NULL_HANDLE;
VkDescriptorImageInfo m_descInfo; VkDescriptorImageInfo m_descInfo;
VkDeviceSize m_gpuOffset; VkDeviceSize m_gpuOffset;
~VulkanTextureSA() ~VulkanTextureSA()
@ -1246,7 +1278,8 @@ public:
void setClampMode(TextureClampMode mode) 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() void deleteUploadObjects()
@ -1308,7 +1341,7 @@ public:
size_t offset = 0; size_t offset = 0;
for (int i=0 ; i<regionCount ; ++i) 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.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copyRegions[i].imageSubresource.mipLevel = i; copyRegions[i].imageSubresource.mipLevel = i;
@ -1323,7 +1356,7 @@ public:
width /= 2; width /= 2;
if (height > 1) if (height > 1)
height /= 2; height /= 2;
offset += srcRowPitch; offset += regionPitch;
} }
/* Put the copy command into the command buffer */ /* Put the copy command into the command buffer */
@ -1356,7 +1389,6 @@ class VulkanTextureD : public GraphicsDataNode<ITextureD>
VulkanContext* m_ctx; VulkanContext* m_ctx;
std::unique_ptr<uint8_t[]> m_stagingBuf; std::unique_ptr<uint8_t[]> m_stagingBuf;
size_t m_cpuSz; size_t m_cpuSz;
VkDeviceSize m_srcRowPitch;
VkDeviceSize m_cpuOffsets[2]; VkDeviceSize m_cpuOffsets[2];
VkFormat m_vkFmt; VkFormat m_vkFmt;
int m_validSlots = 0; int m_validSlots = 0;
@ -1369,13 +1401,11 @@ class VulkanTextureD : public GraphicsDataNode<ITextureD>
{ {
case TextureFormat::RGBA8: case TextureFormat::RGBA8:
pfmt = VK_FORMAT_R8G8B8A8_UNORM; pfmt = VK_FORMAT_R8G8B8A8_UNORM;
m_srcRowPitch = width * 4; m_cpuSz = width * height * 4;
m_cpuSz = m_srcRowPitch * height;
break; break;
case TextureFormat::I8: case TextureFormat::I8:
pfmt = VK_FORMAT_R8_UNORM; pfmt = VK_FORMAT_R8_UNORM;
m_srcRowPitch = width; m_cpuSz = width * height;
m_cpuSz = m_srcRowPitch * height;
break; break;
default: default:
Log.report(logvisor::Fatal, "unsupported tex format"); Log.report(logvisor::Fatal, "unsupported tex format");
@ -1436,6 +1466,7 @@ class VulkanTextureD : public GraphicsDataNode<ITextureD>
texCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; texCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
texCreateInfo.flags = 0; texCreateInfo.flags = 0;
setClampMode(clampMode);
for (int i=0 ; i<2 ; ++i) for (int i=0 ; i<2 ; ++i)
{ {
/* bind cpu memory */ /* bind cpu memory */
@ -1444,7 +1475,7 @@ class VulkanTextureD : public GraphicsDataNode<ITextureD>
/* create gpu image */ /* create gpu image */
ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_gpuTex[i])); 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; m_descInfo[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
} }
} }
@ -1454,14 +1485,16 @@ public:
VkDeviceMemory m_cpuMem; VkDeviceMemory m_cpuMem;
VkImage m_gpuTex[2]; VkImage m_gpuTex[2];
VkImageView m_gpuView[2]; VkImageView m_gpuView[2];
VkSampler m_sampler = VK_NULL_HANDLE;
VkDeviceSize m_gpuOffset[2]; VkDeviceSize m_gpuOffset[2];
VkDescriptorImageInfo m_descInfo[2]; VkDescriptorImageInfo m_descInfo[2];
~VulkanTextureD(); ~VulkanTextureD();
void setClampMode(TextureClampMode mode) void setClampMode(TextureClampMode mode)
{ {
MakeSampler(m_ctx, m_sampler, mode, 1);
for (int i=0 ; i<2 ; ++i) 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); void load(const void* data, size_t sz);
@ -1526,7 +1559,7 @@ class VulkanTextureR : public GraphicsDataNode<ITextureR>
friend struct VulkanCommandQueue; friend struct VulkanCommandQueue;
size_t m_width = 0; size_t m_width = 0;
size_t m_height = 0; size_t m_height = 0;
size_t m_samples = 0; VkSampleCountFlags m_samplesColor, m_samplesDepth;
TextureClampMode m_clampMode; TextureClampMode m_clampMode;
size_t m_colorBindCount; size_t m_colorBindCount;
@ -1549,7 +1582,7 @@ class VulkanTextureR : public GraphicsDataNode<ITextureR>
texCreateInfo.extent.depth = 1; texCreateInfo.extent.depth = 1;
texCreateInfo.mipLevels = 1; texCreateInfo.mipLevels = 1;
texCreateInfo.arrayLayers = 1; texCreateInfo.arrayLayers = 1;
texCreateInfo.samples = VkSampleCountFlagBits(m_samples); texCreateInfo.samples = VkSampleCountFlagBits(m_samplesColor);
texCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; texCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
texCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; texCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
texCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 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)); ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_colorTex));
/* depth target */ /* depth target */
texCreateInfo.samples = VkSampleCountFlagBits(m_samplesDepth);
texCreateInfo.format = VK_FORMAT_D32_SFLOAT; texCreateInfo.format = VK_FORMAT_D32_SFLOAT;
texCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 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)); ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_depthTex));
@ -1603,7 +1637,7 @@ class VulkanTextureR : public GraphicsDataNode<ITextureR>
memAlloc.allocationSize += memReqs.size; memAlloc.allocationSize += memReqs.size;
memTypeBits &= memReqs.memoryTypeBits; 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; m_colorBindDescInfo[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
} }
@ -1620,7 +1654,7 @@ class VulkanTextureR : public GraphicsDataNode<ITextureR>
memAlloc.allocationSize += memReqs.size; memAlloc.allocationSize += memReqs.size;
memTypeBits &= memReqs.memoryTypeBits; 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; m_depthBindDescInfo[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
} }
@ -1709,10 +1743,12 @@ class VulkanTextureR : public GraphicsDataNode<ITextureR>
VulkanContext* m_ctx; VulkanContext* m_ctx;
VulkanCommandQueue* m_q; VulkanCommandQueue* m_q;
VulkanTextureR(const boo::ObjToken<BaseGraphicsData>& parent, VulkanContext* ctx, VulkanCommandQueue* 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) size_t colorBindCount, size_t depthBindCount)
: GraphicsDataNode<ITextureR>(parent), m_ctx(ctx), m_q(q), : 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_clampMode(clampMode),
m_colorBindCount(colorBindCount), m_colorBindCount(colorBindCount),
m_depthBindCount(depthBindCount) m_depthBindCount(depthBindCount)
@ -1722,11 +1758,12 @@ class VulkanTextureR : public GraphicsDataNode<ITextureR>
if (depthBindCount > MAX_BIND_TEXS) if (depthBindCount > MAX_BIND_TEXS)
Log.report(logvisor::Fatal, "too many depth bindings for render texture"); 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); Setup(ctx);
} }
public: public:
size_t samples() const {return m_samples;}
VkDeviceMemory m_gpuMem = VK_NULL_HANDLE; VkDeviceMemory m_gpuMem = VK_NULL_HANDLE;
VkImage m_colorTex = VK_NULL_HANDLE; VkImage m_colorTex = VK_NULL_HANDLE;
@ -1750,12 +1787,15 @@ public:
VkImageLayout m_colorBindLayout[MAX_BIND_TEXS] = {}; VkImageLayout m_colorBindLayout[MAX_BIND_TEXS] = {};
VkImageLayout m_depthBindLayout[MAX_BIND_TEXS] = {}; VkImageLayout m_depthBindLayout[MAX_BIND_TEXS] = {};
VkSampler m_sampler = VK_NULL_HANDLE;
void setClampMode(TextureClampMode mode) void setClampMode(TextureClampMode mode)
{ {
MakeSampler(m_ctx, m_sampler, mode, 1);
for (size_t i=0 ; i<m_colorBindCount ; ++i) 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) 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(); void doDestroy();
@ -2006,7 +2046,7 @@ public:
multisampleInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; multisampleInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
multisampleInfo.pNext = nullptr; multisampleInfo.pNext = nullptr;
multisampleInfo.flags = 0; multisampleInfo.flags = 0;
multisampleInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; multisampleInfo.rasterizationSamples = VkSampleCountFlagBits(m_ctx->m_sampleCountColor);
VkPipelineDepthStencilStateCreateInfo depthStencilInfo = {}; VkPipelineDepthStencilStateCreateInfo depthStencilInfo = {};
depthStencilInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; 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, SetImageLayout(cmdBuf, csource->m_colorTex, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1, 1); 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 = {}; VkImageResolve resolveInfo = {};
resolveInfo.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; resolveInfo.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@ -2798,72 +2838,176 @@ struct VulkanCommandQueue : IGraphicsCommandQueue
vk::CmdEndRenderPass(cmdBuf); 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 (color && ctexture->m_colorBindCount)
{ {
if (ctexture == m_boundTarget.get()) if (ctexture->m_samplesColor <= 1)
SetImageLayout(cmdBuf, ctexture->m_colorTex, VK_IMAGE_ASPECT_COLOR_BIT, {
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1, 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, if (ctexture == m_boundTarget.get())
ctexture->m_colorBindLayout[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 1); 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; SetImageLayout(cmdBuf, ctexture->m_colorBindTex[bindIdx], VK_IMAGE_ASPECT_COLOR_BIT,
copyInfo.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; ctexture->m_colorBindLayout[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 1);
vk::CmdCopyImage(cmdBuf, copyInfo.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
ctexture->m_colorTex, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, copyInfo.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
ctexture->m_colorBindTex[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, &copyInfo);
if (ctexture == m_boundTarget.get()) vk::CmdCopyImage(cmdBuf,
SetImageLayout(cmdBuf, ctexture->m_colorTex, VK_IMAGE_ASPECT_COLOR_BIT, ctexture->m_colorTex, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, 1); ctexture->m_colorBindTex[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, &copyInfo);
SetImageLayout(cmdBuf, ctexture->m_colorBindTex[bindIdx], VK_IMAGE_ASPECT_COLOR_BIT, if (ctexture == m_boundTarget.get())
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1, 1); SetImageLayout(cmdBuf, ctexture->m_colorTex, VK_IMAGE_ASPECT_COLOR_BIT,
ctexture->m_colorBindLayout[bindIdx] = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 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 (depth && ctexture->m_depthBindCount)
{ {
if (ctexture == m_boundTarget.get()) if (ctexture->m_samplesDepth <= 1)
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); 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, if (ctexture == m_boundTarget.get())
ctexture->m_depthBindLayout[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 1); 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; SetImageLayout(cmdBuf, ctexture->m_depthBindTex[bindIdx], VK_IMAGE_ASPECT_DEPTH_BIT,
copyInfo.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; ctexture->m_depthBindLayout[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 1);
vk::CmdCopyImage(cmdBuf, copyInfo.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
ctexture->m_depthTex, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, copyInfo.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
ctexture->m_depthBindTex[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, &copyInfo);
if (ctexture == m_boundTarget.get()) vk::CmdCopyImage(cmdBuf,
SetImageLayout(cmdBuf, ctexture->m_depthTex, VK_IMAGE_ASPECT_DEPTH_BIT, ctexture->m_depthTex, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, 1); ctexture->m_depthBindTex[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, &copyInfo);
SetImageLayout(cmdBuf, ctexture->m_depthBindTex[bindIdx], VK_IMAGE_ASPECT_DEPTH_BIT, if (ctexture == m_boundTarget.get())
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1, 1); SetImageLayout(cmdBuf, ctexture->m_depthTex, VK_IMAGE_ASPECT_DEPTH_BIT,
ctexture->m_depthBindLayout[bindIdx] = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 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); vk::CmdBeginRenderPass(cmdBuf, &m_boundTarget.cast<VulkanTextureR>()->m_passBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
@ -3083,9 +3227,8 @@ void VulkanTextureD::unmap()
m_validSlots = 0; m_validSlots = 0;
} }
VulkanDataFactoryImpl::VulkanDataFactoryImpl(IGraphicsContext* parent, VulkanDataFactoryImpl::VulkanDataFactoryImpl(IGraphicsContext* parent, VulkanContext* ctx)
VulkanContext* ctx, uint32_t drawSamples) : m_parent(parent), m_ctx(ctx)
: m_parent(parent), m_ctx(ctx), m_drawSamples(drawSamples)
{ {
VkDescriptorSetLayoutBinding layoutBindings[BOO_GLSL_MAX_UNIFORM_COUNT + BOO_GLSL_MAX_TEXTURE_COUNT]; VkDescriptorSetLayoutBinding layoutBindings[BOO_GLSL_MAX_UNIFORM_COUNT + BOO_GLSL_MAX_TEXTURE_COUNT];
for (int i=0 ; i<BOO_GLSL_MAX_UNIFORM_COUNT ; ++i) for (int i=0 ; i<BOO_GLSL_MAX_UNIFORM_COUNT ; ++i)
@ -3124,7 +3267,7 @@ VulkanDataFactoryImpl::VulkanDataFactoryImpl(IGraphicsContext* parent,
/* color attachment */ /* color attachment */
attachments[0].format = ctx->m_displayFormat; 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].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
@ -3135,7 +3278,7 @@ VulkanDataFactoryImpl::VulkanDataFactoryImpl(IGraphicsContext* parent,
/* depth attachment */ /* depth attachment */
attachments[1].format = VK_FORMAT_D32_SFLOAT; 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].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; 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); VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent);
VulkanCommandQueue* q = static_cast<VulkanCommandQueue*>(factory.m_parent->getCommandQueue()); 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)}; clampMode, colorBindCount, depthBindCount)};
} }
@ -3489,6 +3632,8 @@ void VulkanDataFactoryImpl::commitTransaction
for (ITextureD& tex : *data->m_DTexs) for (ITextureD& tex : *data->m_DTexs)
texMemSize = static_cast<VulkanTextureD&>(tex).sizeForGPU(m_ctx, texMemTypeBits, texMemSize); 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 */ /* allocate memory and place textures */
if (bufMemSize) if (bufMemSize)
{ {
@ -3546,7 +3691,6 @@ void VulkanDataFactoryImpl::commitTransaction
submitInfo.pCommandBuffers = &m_ctx->m_loadCmdBuf; submitInfo.pCommandBuffers = &m_ctx->m_loadCmdBuf;
/* Take exclusive lock here and submit queue */ /* 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::QueueWaitIdle(m_ctx->m_queue));
ThrowIfFailed(vk::QueueSubmit(m_ctx->m_queue, 1, &submitInfo, VK_NULL_HANDLE)); 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); return new struct VulkanCommandQueue(ctx, windowCtx, parent);
} }
IGraphicsDataFactory* _NewVulkanDataFactory(IGraphicsContext* parent, VulkanContext* ctx, IGraphicsDataFactory* _NewVulkanDataFactory(IGraphicsContext* parent, VulkanContext* ctx)
uint32_t drawSamples)
{ {
return new class VulkanDataFactoryImpl(parent, ctx, drawSamples); return new class VulkanDataFactoryImpl(parent, ctx);
} }
} }

View File

@ -222,6 +222,7 @@ int ApplicationRun(IApplication::EPlatformType platform,
SystemStringView friendlyName, SystemStringView friendlyName,
SystemStringView pname, SystemStringView pname,
const std::vector<SystemString>& args, const std::vector<SystemString>& args,
std::string_view gfxApi,
uint32_t samples, uint32_t samples,
uint32_t anisotropy, uint32_t anisotropy,
bool singleInstance) bool singleInstance)

View File

@ -36,8 +36,7 @@ namespace boo
{ {
static logvisor::Module Log("boo::ApplicationUWP"); static logvisor::Module Log("boo::ApplicationUWP");
std::shared_ptr<IWindow> _WindowUWPNew(SystemStringView title, Boo3DAppContextUWP& d3dCtx, std::shared_ptr<IWindow> _WindowUWPNew(SystemStringView title, Boo3DAppContextUWP& d3dCtx);
uint32_t sampleCount);
class ApplicationUWP final : public IApplication class ApplicationUWP final : public IApplication
{ {
@ -260,7 +259,7 @@ public:
void _setWindow(CoreWindow^ window) void _setWindow(CoreWindow^ window)
{ {
m_window = _WindowUWPNew(m_friendlyName, m_3dCtx, 1); m_window = _WindowUWPNew(m_friendlyName, m_3dCtx);
} }
}; };

View File

@ -67,8 +67,7 @@ namespace boo
static logvisor::Module Log("boo::ApplicationWin32"); static logvisor::Module Log("boo::ApplicationWin32");
Win32Cursors WIN32_CURSORS; Win32Cursors WIN32_CURSORS;
std::shared_ptr<IWindow> _WindowWin32New(SystemStringView title, Boo3DAppContextWin32& d3dCtx, std::shared_ptr<IWindow> _WindowWin32New(SystemStringView title, Boo3DAppContextWin32& d3dCtx);
uint32_t sampleCount);
class ApplicationWin32 final : public IApplication class ApplicationWin32 final : public IApplication
{ {
@ -97,6 +96,9 @@ public:
SystemStringView friendlyName, SystemStringView friendlyName,
SystemStringView pname, SystemStringView pname,
const std::vector<SystemString>& args, const std::vector<SystemString>& args,
std::string_view gfxApi,
uint32_t samples,
uint32_t anisotropy,
bool singleInstance) bool singleInstance)
: m_callback(callback), : m_callback(callback),
m_uniqueName(uniqueName), m_uniqueName(uniqueName),
@ -105,6 +107,16 @@ public:
m_args(args), m_args(args),
m_singleInstance(singleInstance) 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"); HMODULE dxgilib = LoadLibraryW(L"dxgi.dll");
if (!dxgilib) if (!dxgilib)
Log.report(logvisor::Fatal, "unable to load dxgi.dll"); Log.report(logvisor::Fatal, "unable to load dxgi.dll");
@ -119,6 +131,30 @@ public:
#if BOO_HAS_VULKAN #if BOO_HAS_VULKAN
bool useVulkan = true; bool useVulkan = true;
#endif #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) for (const SystemString& arg : args)
{ {
#if BOO_HAS_VULKAN #if BOO_HAS_VULKAN
@ -127,9 +163,9 @@ public:
useVulkan = false; useVulkan = false;
yes12 = true; yes12 = true;
} }
if (!arg.compare(L"--d3d11")) if (!arg.compare(L"--vulkan"))
{ {
useVulkan = false; noD3d = true;
} }
if (!arg.compare(L"--gl")) if (!arg.compare(L"--gl"))
{ {
@ -144,40 +180,6 @@ public:
#endif #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 #if _WIN32_WINNT_WIN10
HMODULE d3d12lib = nullptr; HMODULE d3d12lib = nullptr;
if (yes12 && !noD3d) if (yes12 && !noD3d)
@ -303,11 +305,15 @@ public:
device->GetParent(__uuidof(IDXGIAdapter), &adapter); device->GetParent(__uuidof(IDXGIAdapter), &adapter);
adapter->GetParent(__uuidof(IDXGIFactory2), &m_3dCtx.m_ctx11.m_dxFactory); 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 */ /* Build default sampler here */
CD3D11_SAMPLER_DESC sampDesc(D3D11_DEFAULT); CD3D11_SAMPLER_DESC sampDesc(D3D11_DEFAULT);
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressW = 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]); m_3dCtx.m_ctx11.m_dev->CreateSamplerState(&sampDesc, &m_3dCtx.m_ctx11.m_ss[0]);
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER; sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
@ -324,6 +330,40 @@ public:
return; 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 */ /* Finally try OpenGL */
{ {
/* Obtain DXGI Factory */ /* Obtain DXGI Factory */
@ -425,7 +465,7 @@ public:
/* New-window message (coalesced onto main thread) */ /* New-window message (coalesced onto main thread) */
std::unique_lock<std::mutex> lk(m_nwmt); std::unique_lock<std::mutex> lk(m_nwmt);
SystemStringView* title = reinterpret_cast<SystemStringView*>(msg.wParam); SystemStringView* title = reinterpret_cast<SystemStringView*>(msg.wParam);
m_mwret = newWindow(*title, 1); m_mwret = newWindow(*title);
lk.unlock(); lk.unlock();
m_nwcv.notify_one(); m_nwcv.notify_one();
continue; continue;
@ -481,7 +521,7 @@ public:
std::mutex m_nwmt; std::mutex m_nwmt;
std::condition_variable m_nwcv; std::condition_variable m_nwcv;
std::shared_ptr<IWindow> m_mwret; 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) if (GetCurrentThreadId() != g_mainThreadId)
{ {
@ -494,7 +534,7 @@ public:
return ret; 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()); HWND hwnd = HWND(window->getPlatformHandle());
m_allWindows[hwnd] = window; m_allWindows[hwnd] = window;
return window; return window;
@ -508,6 +548,9 @@ int ApplicationRun(IApplication::EPlatformType platform,
SystemStringView friendlyName, SystemStringView friendlyName,
SystemStringView pname, SystemStringView pname,
const std::vector<SystemString>& args, const std::vector<SystemString>& args,
std::string_view gfxApi,
uint32_t samples,
uint32_t anisotropy,
bool singleInstance) bool singleInstance)
{ {
std::string thrName = WCSTMBS(friendlyName.data()) + " Main Thread"; std::string thrName = WCSTMBS(friendlyName.data()) + " Main Thread";
@ -522,15 +565,8 @@ int ApplicationRun(IApplication::EPlatformType platform,
/* HI-DPI support */ /* HI-DPI support */
HMODULE shcoreLib = LoadLibraryW(L"Shcore.dll"); HMODULE shcoreLib = LoadLibraryW(L"Shcore.dll");
if (shcoreLib) if (shcoreLib)
{
PFN_SetProcessDpiAwareness MySetProcessDpiAwareness =
(PFN_SetProcessDpiAwareness)GetProcAddress(shcoreLib, "SetProcessDpiAwareness");
if (MySetProcessDpiAwareness)
MySetProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE);
MyGetScaleFactorForMonitor = MyGetScaleFactorForMonitor =
(PFN_GetScaleFactorForMonitor)GetProcAddress(shcoreLib, "GetScaleFactorForMonitor"); (PFN_GetScaleFactorForMonitor)GetProcAddress(shcoreLib, "GetScaleFactorForMonitor");
}
#endif #endif
WIN32_CURSORS.m_arrow = LoadCursor(nullptr, IDC_ARROW); WIN32_CURSORS.m_arrow = LoadCursor(nullptr, IDC_ARROW);
@ -558,7 +594,8 @@ int ApplicationRun(IApplication::EPlatformType platform,
wndClass.hCursor = WIN32_CURSORS.m_arrow; wndClass.hCursor = WIN32_CURSORS.m_arrow;
ATOM a = RegisterClassW(&wndClass); 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(); return APP->run();
} }

View File

@ -13,12 +13,12 @@
#if BOO_HAS_VULKAN #if BOO_HAS_VULKAN
#include "boo/graphicsdev/Vulkan.hpp" #include "boo/graphicsdev/Vulkan.hpp"
#endif #endif
#include "boo/graphicsdev/GL.hpp"
extern DWORD g_mainThreadId; extern DWORD g_mainThreadId;
#if _WIN32_WINNT_WINBLUE && !WINDOWS_STORE #if _WIN32_WINNT_WINBLUE && !WINDOWS_STORE
#include <ShellScalingApi.h> #include <ShellScalingApi.h>
typedef HRESULT (WINAPI* PFN_SetProcessDpiAwareness)( _In_ PROCESS_DPI_AWARENESS );
typedef HRESULT (WINAPI* PFN_GetScaleFactorForMonitor)( _In_ HMONITOR, _Out_ DEVICE_SCALE_FACTOR *); typedef HRESULT (WINAPI* PFN_GetScaleFactorForMonitor)( _In_ HMONITOR, _Out_ DEVICE_SCALE_FACTOR *);
extern PFN_GetScaleFactorForMonitor MyGetScaleFactorForMonitor; extern PFN_GetScaleFactorForMonitor MyGetScaleFactorForMonitor;
#endif #endif
@ -43,6 +43,8 @@ struct OGLContext
int m_fsCountDown = 0; int m_fsCountDown = 0;
}; };
std::unordered_map<const boo::IWindow*, Window> m_windows; std::unordered_map<const boo::IWindow*, Window> m_windows;
boo::GLContext m_glCtx;
}; };
template <class W> template <class W>

View File

@ -44,6 +44,9 @@ struct D3D12Context
size_t width, height; size_t width, height;
}; };
std::unordered_map<const boo::IWindow*, Window> m_windows; std::unordered_map<const boo::IWindow*, Window> m_windows;
uint32_t m_sampleCount = 1;
uint32_t m_anisotropy = 1;
}; };
struct D3D11Context struct D3D11Context
@ -63,6 +66,9 @@ struct D3D11Context
DXGI_MODE_DESC m_fsdesc = {}; DXGI_MODE_DESC m_fsdesc = {};
}; };
std::unordered_map<const boo::IWindow*, Window> m_windows; std::unordered_map<const boo::IWindow*, Window> m_windows;
uint32_t m_sampleCount = 1;
uint32_t m_anisotropy = 1;
}; };
struct Boo3DAppContext struct Boo3DAppContext

View File

@ -58,7 +58,7 @@ public:
IWindowCallback* m_callback; IWindowCallback* m_callback;
GraphicsContextUWPD3D(EGraphicsAPI api, IWindow* parentWindow, Agile<CoreWindow>& coreWindow, GraphicsContextUWPD3D(EGraphicsAPI api, IWindow* parentWindow, Agile<CoreWindow>& coreWindow,
Boo3DAppContextUWP& b3dCtx, uint32_t sampleCount) Boo3DAppContextUWP& b3dCtx)
: GraphicsContextUWP(api, parentWindow, b3dCtx) : GraphicsContextUWP(api, parentWindow, b3dCtx)
{ {
/* Create Swap Chain */ /* Create Swap Chain */
@ -83,7 +83,7 @@ public:
D3D12Context::Window& w = insIt.first->second; D3D12Context::Window& w = insIt.first->second;
ID3D12CommandQueue* cmdQueue; 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); m_commandQueue = _NewD3D12CommandQueue(&b3dCtx.m_ctx12, &w, this, &cmdQueue);
scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
@ -120,7 +120,7 @@ public:
fbRes->GetDesc(&resDesc); fbRes->GetDesc(&resDesc);
w.width = resDesc.Width; w.width = resDesc.Width;
w.height = resDesc.Height; 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); m_commandQueue = _NewD3D11CommandQueue(&b3dCtx.m_ctx11, &insIt.first->second, this);
if (FAILED(m_swapChain->GetContainingOutput(&m_output))) if (FAILED(m_swapChain->GetContainingOutput(&m_output)))
@ -337,7 +337,7 @@ public:
}; };
EventReceiver^ m_eventReceiver; EventReceiver^ m_eventReceiver;
WindowUWP(SystemStringView title, Boo3DAppContextUWP& b3dCtx, uint32_t sampleCount) WindowUWP(SystemStringView title, Boo3DAppContextUWP& b3dCtx)
: m_coreWindow(CoreWindow::GetForCurrentThread()), : m_coreWindow(CoreWindow::GetForCurrentThread()),
m_eventReceiver(ref new EventReceiver(*this)) m_eventReceiver(ref new EventReceiver(*this))
{ {
@ -346,7 +346,7 @@ public:
if (b3dCtx.m_ctx12.m_dev) if (b3dCtx.m_ctx12.m_dev)
api = IGraphicsContext::EGraphicsAPI::D3D12; api = IGraphicsContext::EGraphicsAPI::D3D12;
#endif #endif
m_gfxCtx.reset(new GraphicsContextUWPD3D(api, this, m_coreWindow, b3dCtx, sampleCount)); m_gfxCtx.reset(new GraphicsContextUWPD3D(api, this, m_coreWindow, b3dCtx));
setTitle(title); setTitle(title);
m_bounds = m_coreWindow->Bounds; m_bounds = m_coreWindow->Bounds;
@ -628,10 +628,9 @@ public:
}; };
std::shared_ptr<IWindow> _WindowUWPNew(SystemStringView title, Boo3DAppContextUWP& d3dCtx, std::shared_ptr<IWindow> _WindowUWPNew(SystemStringView title, Boo3DAppContextUWP& d3dCtx)
uint32_t sampleCount)
{ {
return std::make_shared<WindowUWP>(title, d3dCtx, sampleCount); return std::make_shared<WindowUWP>(title, d3dCtx);
} }
} }

View File

@ -31,18 +31,17 @@ static logvisor::Module Log("boo::WindowWin32");
#if _WIN32_WINNT_WIN10 #if _WIN32_WINNT_WIN10
IGraphicsCommandQueue* _NewD3D12CommandQueue(D3D12Context* ctx, D3D12Context::Window* windowCtx, IGraphicsContext* parent, IGraphicsCommandQueue* _NewD3D12CommandQueue(D3D12Context* ctx, D3D12Context::Window* windowCtx, IGraphicsContext* parent,
ID3D12CommandQueue** cmdQueueOut); ID3D12CommandQueue** cmdQueueOut);
IGraphicsDataFactory* _NewD3D12DataFactory(D3D12Context* ctx, IGraphicsContext* parent, uint32_t sampleCount); IGraphicsDataFactory* _NewD3D12DataFactory(D3D12Context* ctx, IGraphicsContext* parent);
#endif #endif
IGraphicsCommandQueue* _NewD3D11CommandQueue(D3D11Context* ctx, D3D11Context::Window* windowCtx, IGraphicsContext* parent); 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); IGraphicsCommandQueue* _NewGLCommandQueue(IGraphicsContext* parent, GLContext* glCtx);
IGraphicsDataFactory* _NewGLDataFactory(IGraphicsContext* parent, GLContext* glCtx); IGraphicsDataFactory* _NewGLDataFactory(IGraphicsContext* parent, GLContext* glCtx);
#if BOO_HAS_VULKAN #if BOO_HAS_VULKAN
IGraphicsCommandQueue* _NewVulkanCommandQueue(VulkanContext* ctx, IGraphicsCommandQueue* _NewVulkanCommandQueue(VulkanContext* ctx,
VulkanContext::Window* windowCtx, VulkanContext::Window* windowCtx,
IGraphicsContext* parent); IGraphicsContext* parent);
IGraphicsDataFactory* _NewVulkanDataFactory(IGraphicsContext* parent, VulkanContext* ctx, IGraphicsDataFactory* _NewVulkanDataFactory(IGraphicsContext* parent, VulkanContext* ctx);
uint32_t drawSamples);
#endif #endif
struct GraphicsContextWin32 : IGraphicsContext struct GraphicsContextWin32 : IGraphicsContext
@ -75,7 +74,7 @@ public:
IWindowCallback* m_callback; IWindowCallback* m_callback;
GraphicsContextWin32D3D(EGraphicsAPI api, IWindow* parentWindow, HWND hwnd, GraphicsContextWin32D3D(EGraphicsAPI api, IWindow* parentWindow, HWND hwnd,
Boo3DAppContextWin32& b3dCtx, uint32_t sampleCount) Boo3DAppContextWin32& b3dCtx)
: GraphicsContextWin32(api, parentWindow, b3dCtx) : GraphicsContextWin32(api, parentWindow, b3dCtx)
{ {
/* Create Swap Chain */ /* Create Swap Chain */
@ -94,7 +93,7 @@ public:
D3D12Context::Window& w = insIt.first->second; D3D12Context::Window& w = insIt.first->second;
ID3D12CommandQueue* cmdQueue; 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); m_commandQueue = _NewD3D12CommandQueue(&b3dCtx.m_ctx12, &w, this, &cmdQueue);
scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
@ -133,7 +132,7 @@ public:
fbRes->GetDesc(&resDesc); fbRes->GetDesc(&resDesc);
w.width = resDesc.Width; w.width = resDesc.Width;
w.height = resDesc.Height; 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); m_commandQueue = _NewD3D11CommandQueue(&b3dCtx.m_ctx11, &insIt.first->second, this);
if (FAILED(m_swapChain->GetContainingOutput(&m_output))) if (FAILED(m_swapChain->GetContainingOutput(&m_output)))
@ -211,7 +210,7 @@ public:
IWindowCallback* m_callback; IWindowCallback* m_callback;
GraphicsContextWin32GL(EGraphicsAPI api, IWindow* parentWindow, HWND hwnd, GraphicsContextWin32GL(EGraphicsAPI api, IWindow* parentWindow, HWND hwnd,
Boo3DAppContextWin32& b3dCtx, uint32_t sampleCount) Boo3DAppContextWin32& b3dCtx)
: GraphicsContextWin32(api, parentWindow, b3dCtx) : GraphicsContextWin32(api, parentWindow, b3dCtx)
{ {
@ -283,8 +282,8 @@ public:
Log.report(logvisor::Fatal, "unable to share contexts"); Log.report(logvisor::Fatal, "unable to share contexts");
m_3dCtx.m_ctxOgl.m_lastContext = w.m_mainContext; m_3dCtx.m_ctxOgl.m_lastContext = w.m_mainContext;
m_dataFactory = _NewGLDataFactory(this, sampleCount); m_dataFactory = _NewGLDataFactory(this, &b3dCtx.m_ctxOgl.m_glCtx);
m_commandQueue = _NewGLCommandQueue(this); m_commandQueue = _NewGLCommandQueue(this, &b3dCtx.m_ctxOgl.m_glCtx);
} }
~GraphicsContextWin32GL() ~GraphicsContextWin32GL()
@ -398,7 +397,6 @@ struct GraphicsContextWin32Vulkan : GraphicsContextWin32
VkSurfaceKHR m_surface = VK_NULL_HANDLE; VkSurfaceKHR m_surface = VK_NULL_HANDLE;
VkFormat m_format = VK_FORMAT_UNDEFINED; VkFormat m_format = VK_FORMAT_UNDEFINED;
VkColorSpaceKHR m_colorspace; VkColorSpaceKHR m_colorspace;
uint32_t m_sampleCount;
IGraphicsCommandQueue* m_commandQueue = nullptr; IGraphicsCommandQueue* m_commandQueue = nullptr;
IGraphicsDataFactory* m_dataFactory = nullptr; IGraphicsDataFactory* m_dataFactory = nullptr;
@ -416,9 +414,9 @@ public:
IWindowCallback* m_callback; IWindowCallback* m_callback;
GraphicsContextWin32Vulkan(IWindow* parentWindow, HINSTANCE appInstance, HWND hwnd, GraphicsContextWin32Vulkan(IWindow* parentWindow, HINSTANCE appInstance, HWND hwnd,
VulkanContext* ctx, Boo3DAppContextWin32& b3dCtx, uint32_t drawSamples) VulkanContext* ctx, Boo3DAppContextWin32& b3dCtx)
: GraphicsContextWin32(EGraphicsAPI::Vulkan, parentWindow, 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); HMONITOR testMon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY);
ComPtr<IDXGIAdapter1> adapter; ComPtr<IDXGIAdapter1> adapter;
@ -586,7 +584,7 @@ public:
m_ctx->initSwapChain(*m_windowCtx, m_surface, m_format, m_colorspace); 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); m_commandQueue = _NewVulkanCommandQueue(m_ctx, m_ctx->m_windows[m_parentWindow].get(), this);
return true; return true;
} }
@ -960,7 +958,7 @@ class WindowWin32 : public IWindow
public: public:
WindowWin32(SystemStringView title, Boo3DAppContextWin32& b3dCtx, uint32_t sampleCount) WindowWin32(SystemStringView title, Boo3DAppContextWin32& b3dCtx)
{ {
m_hwnd = CreateWindowW(L"BooWindow", title.data(), WS_OVERLAPPEDWINDOW, m_hwnd = CreateWindowW(L"BooWindow", title.data(), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
@ -971,8 +969,7 @@ public:
#if BOO_HAS_VULKAN #if BOO_HAS_VULKAN
if (b3dCtx.m_vulkanDxFactory) if (b3dCtx.m_vulkanDxFactory)
{ {
m_gfxCtx.reset(new GraphicsContextWin32Vulkan(this, wndInstance, m_hwnd, &g_VulkanContext, m_gfxCtx.reset(new GraphicsContextWin32Vulkan(this, wndInstance, m_hwnd, &g_VulkanContext, b3dCtx));
b3dCtx, sampleCount));
if (m_gfxCtx->initializeContext(nullptr)) if (m_gfxCtx->initializeContext(nullptr))
return; return;
} }
@ -985,11 +982,11 @@ public:
if (b3dCtx.m_ctxOgl.m_dxFactory) if (b3dCtx.m_ctxOgl.m_dxFactory)
{ {
m_gfxCtx.reset(new GraphicsContextWin32GL(IGraphicsContext::EGraphicsAPI::OpenGL3_3, m_gfxCtx.reset(new GraphicsContextWin32GL(IGraphicsContext::EGraphicsAPI::OpenGL3_3,
this, m_hwnd, b3dCtx, sampleCount)); this, m_hwnd, b3dCtx));
m_openGL = true; m_openGL = true;
return; return;
} }
m_gfxCtx.reset(new GraphicsContextWin32D3D(api, this, m_hwnd, b3dCtx, sampleCount)); m_gfxCtx.reset(new GraphicsContextWin32D3D(api, this, m_hwnd, b3dCtx));
} }
~WindowWin32() ~WindowWin32()
@ -1573,10 +1570,9 @@ public:
}; };
std::shared_ptr<IWindow> _WindowWin32New(SystemStringView title, Boo3DAppContextWin32& d3dCtx, std::shared_ptr<IWindow> _WindowWin32New(SystemStringView title, Boo3DAppContextWin32& d3dCtx)
uint32_t sampleCount)
{ {
return std::make_shared<WindowWin32>(title, d3dCtx, sampleCount); return std::make_shared<WindowWin32>(title, d3dCtx);
} }
} }

View File

@ -58,6 +58,7 @@ int ApplicationRun(IApplication::EPlatformType platform,
std::string_view friendlyName, std::string_view friendlyName,
std::string_view pname, std::string_view pname,
const std::vector<std::string>& args, const std::vector<std::string>& args,
std::string_view gfxApi,
uint32_t samples, uint32_t samples,
uint32_t anisotropy, uint32_t anisotropy,
bool singleInstance) bool singleInstance)

@ -1 +1 @@
Subproject commit beee8b397056efcdc33020a26cf69d1039f0f802 Subproject commit f28fa0dbb2e59d02eb659542b28b13f8d1bfe4fb