diff --git a/include/boo/IApplication.hpp b/include/boo/IApplication.hpp index ac1a3bd..4e95e2d 100644 --- a/include/boo/IApplication.hpp +++ b/include/boo/IApplication.hpp @@ -61,6 +61,7 @@ ApplicationRun(IApplication::EPlatformType platform, SystemStringView friendlyName, SystemStringView pname, const std::vector& 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> 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 m_samplers; + bool initVulkan(std::string_view appName); bool enumerateDevices(); void initDevice(); diff --git a/lib/graphicsdev/D3D11.cpp b/lib/graphicsdev/D3D11.cpp index 918b263..8df7910 100644 --- a/lib/graphicsdev/D3D11.cpp +++ b/lib/graphicsdev/D3D11.cpp @@ -158,6 +158,8 @@ class D3D11TextureS : public GraphicsDataNode 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> m_sharedShaders; std::unordered_map 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 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); } } diff --git a/lib/graphicsdev/D3D12.cpp b/lib/graphicsdev/D3D12.cpp index 75dff65..6610f59 100644 --- a/lib/graphicsdev/D3D12.cpp +++ b/lib/graphicsdev/D3D12.cpp @@ -228,6 +228,8 @@ class D3D12TextureS : public GraphicsDataNode 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 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 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> m_sharedShaders; std::unordered_map 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(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); } } diff --git a/lib/graphicsdev/Vulkan.cpp b/lib/graphicsdev/Vulkan.cpp index 2c5f13a..7e6eb36 100644 --- a/lib/graphicsdev/Vulkan.cpp +++ b/lib/graphicsdev/Vulkan.cpp @@ -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> m_sharedShaders; std::vector m_texUnis; public: std::unordered_map 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 { friend class VulkanDataFactory; @@ -1022,7 +1051,7 @@ class VulkanTextureS : public GraphicsDataNode 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 1) height /= 2; - offset += srcRowPitch; + offset += regionPitch; } /* Put the copy command into the command buffer */ @@ -1224,7 +1255,7 @@ class VulkanTextureSA : public GraphicsDataNode 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 1) height /= 2; - offset += srcRowPitch; + offset += regionPitch; } /* Put the copy command into the command buffer */ @@ -1356,7 +1389,6 @@ class VulkanTextureD : public GraphicsDataNode VulkanContext* m_ctx; std::unique_ptr 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 { 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 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 /* 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 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 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 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 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 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 VulkanContext* m_ctx; VulkanCommandQueue* m_q; VulkanTextureR(const boo::ObjToken& 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(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 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 ; im_linearSamplers[int(mode)]; + m_colorBindDescInfo[i].sampler = m_sampler; for (size_t i=0 ; im_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()->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 ; im_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(m_parent); VulkanCommandQueue* q = static_cast(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(tex).sizeForGPU(m_ctx, texMemTypeBits, texMemSize); + std::unique_lock 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 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); } } diff --git a/lib/mac/ApplicationCocoa.mm b/lib/mac/ApplicationCocoa.mm index 2313a64..814c9f2 100644 --- a/lib/mac/ApplicationCocoa.mm +++ b/lib/mac/ApplicationCocoa.mm @@ -222,6 +222,7 @@ int ApplicationRun(IApplication::EPlatformType platform, SystemStringView friendlyName, SystemStringView pname, const std::vector& args, + std::string_view gfxApi, uint32_t samples, uint32_t anisotropy, bool singleInstance) diff --git a/lib/win/ApplicationUWP.cpp b/lib/win/ApplicationUWP.cpp index 3b18d8a..f4c57e1 100644 --- a/lib/win/ApplicationUWP.cpp +++ b/lib/win/ApplicationUWP.cpp @@ -36,8 +36,7 @@ namespace boo { static logvisor::Module Log("boo::ApplicationUWP"); -std::shared_ptr _WindowUWPNew(SystemStringView title, Boo3DAppContextUWP& d3dCtx, - uint32_t sampleCount); +std::shared_ptr _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); } }; diff --git a/lib/win/ApplicationWin32.cpp b/lib/win/ApplicationWin32.cpp index 8d216c8..fd62109 100644 --- a/lib/win/ApplicationWin32.cpp +++ b/lib/win/ApplicationWin32.cpp @@ -67,8 +67,7 @@ namespace boo static logvisor::Module Log("boo::ApplicationWin32"); Win32Cursors WIN32_CURSORS; -std::shared_ptr _WindowWin32New(SystemStringView title, Boo3DAppContextWin32& d3dCtx, - uint32_t sampleCount); +std::shared_ptr _WindowWin32New(SystemStringView title, Boo3DAppContextWin32& d3dCtx); class ApplicationWin32 final : public IApplication { @@ -97,6 +96,9 @@ public: SystemStringView friendlyName, SystemStringView pname, const std::vector& 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 lk(m_nwmt); SystemStringView* title = reinterpret_cast(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 m_mwret; - std::shared_ptr newWindow(SystemStringView title, uint32_t sampleCount) + std::shared_ptr newWindow(SystemStringView title) { if (GetCurrentThreadId() != g_mainThreadId) { @@ -494,7 +534,7 @@ public: return ret; } - std::shared_ptr window = _WindowWin32New(title, m_3dCtx, sampleCount); + std::shared_ptr 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& 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(); } diff --git a/lib/win/Win32Common.hpp b/lib/win/Win32Common.hpp index 656ad35..3aad788 100644 --- a/lib/win/Win32Common.hpp +++ b/lib/win/Win32Common.hpp @@ -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 -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 m_windows; + + boo::GLContext m_glCtx; }; template diff --git a/lib/win/WinCommon.hpp b/lib/win/WinCommon.hpp index b02f4fd..59e3a03 100644 --- a/lib/win/WinCommon.hpp +++ b/lib/win/WinCommon.hpp @@ -44,6 +44,9 @@ struct D3D12Context size_t width, height; }; std::unordered_map 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 m_windows; + + uint32_t m_sampleCount = 1; + uint32_t m_anisotropy = 1; }; struct Boo3DAppContext diff --git a/lib/win/WindowUWP.cpp b/lib/win/WindowUWP.cpp index ac1fdd2..ea41d8a 100644 --- a/lib/win/WindowUWP.cpp +++ b/lib/win/WindowUWP.cpp @@ -58,7 +58,7 @@ public: IWindowCallback* m_callback; GraphicsContextUWPD3D(EGraphicsAPI api, IWindow* parentWindow, Agile& 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 _WindowUWPNew(SystemStringView title, Boo3DAppContextUWP& d3dCtx, - uint32_t sampleCount) +std::shared_ptr _WindowUWPNew(SystemStringView title, Boo3DAppContextUWP& d3dCtx) { - return std::make_shared(title, d3dCtx, sampleCount); + return std::make_shared(title, d3dCtx); } } diff --git a/lib/win/WindowWin32.cpp b/lib/win/WindowWin32.cpp index f70f965..181bac4 100644 --- a/lib/win/WindowWin32.cpp +++ b/lib/win/WindowWin32.cpp @@ -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 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 _WindowWin32New(SystemStringView title, Boo3DAppContextWin32& d3dCtx, - uint32_t sampleCount) +std::shared_ptr _WindowWin32New(SystemStringView title, Boo3DAppContextWin32& d3dCtx) { - return std::make_shared(title, d3dCtx, sampleCount); + return std::make_shared(title, d3dCtx); } } diff --git a/lib/x11/ApplicationUnix.cpp b/lib/x11/ApplicationUnix.cpp index 9b58735..278ff1d 100644 --- a/lib/x11/ApplicationUnix.cpp +++ b/lib/x11/ApplicationUnix.cpp @@ -58,6 +58,7 @@ int ApplicationRun(IApplication::EPlatformType platform, std::string_view friendlyName, std::string_view pname, const std::vector& args, + std::string_view gfxApi, uint32_t samples, uint32_t anisotropy, bool singleInstance) diff --git a/logvisor b/logvisor index beee8b3..f28fa0d 160000 --- a/logvisor +++ b/logvisor @@ -1 +1 @@ -Subproject commit beee8b397056efcdc33020a26cf69d1039f0f802 +Subproject commit f28fa0dbb2e59d02eb659542b28b13f8d1bfe4fb