2018-01-20 21:42:11 +01:00
|
|
|
#include <cstring>
|
|
|
|
|
2018-02-20 13:08:50 +01:00
|
|
|
#include "dxvk_format.h"
|
2017-10-15 17:56:06 +02:00
|
|
|
#include "dxvk_util.h"
|
|
|
|
|
|
|
|
namespace dxvk::util {
|
|
|
|
|
|
|
|
VkPipelineStageFlags pipelineStages(
|
|
|
|
VkShaderStageFlags shaderStages) {
|
|
|
|
VkPipelineStageFlags result = 0;
|
|
|
|
if (shaderStages & VK_SHADER_STAGE_COMPUTE_BIT)
|
|
|
|
result |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
|
|
|
if (shaderStages & VK_SHADER_STAGE_VERTEX_BIT)
|
|
|
|
result |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;
|
|
|
|
if (shaderStages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
|
|
|
|
result |= VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT;
|
|
|
|
if (shaderStages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
|
|
|
|
result |= VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT;
|
|
|
|
if (shaderStages & VK_SHADER_STAGE_GEOMETRY_BIT)
|
|
|
|
result |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
|
|
|
|
if (shaderStages & VK_SHADER_STAGE_FRAGMENT_BIT)
|
|
|
|
result |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-12-10 19:10:17 +01:00
|
|
|
|
|
|
|
uint32_t computeMipLevelCount(VkExtent3D imageSize) {
|
|
|
|
uint32_t maxDim = std::max(imageSize.width, imageSize.height);
|
|
|
|
maxDim = std::max(imageSize.depth, maxDim);
|
|
|
|
uint32_t mipCnt = 0;
|
|
|
|
|
|
|
|
while (maxDim > 0) {
|
|
|
|
mipCnt += 1;
|
|
|
|
maxDim /= 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
return mipCnt;
|
|
|
|
}
|
|
|
|
|
2018-01-20 21:42:11 +01:00
|
|
|
|
|
|
|
void packImageData(
|
2019-06-25 14:17:03 +02:00
|
|
|
void* dstBytes,
|
|
|
|
const void* srcBytes,
|
2018-01-20 21:42:11 +01:00
|
|
|
VkExtent3D blockCount,
|
|
|
|
VkDeviceSize blockSize,
|
|
|
|
VkDeviceSize pitchPerRow,
|
|
|
|
VkDeviceSize pitchPerLayer) {
|
2019-06-25 14:17:03 +02:00
|
|
|
auto dstData = reinterpret_cast< char*>(dstBytes);
|
|
|
|
auto srcData = reinterpret_cast<const char*>(srcBytes);
|
|
|
|
|
2018-01-20 21:42:11 +01:00
|
|
|
const VkDeviceSize bytesPerRow = blockCount.width * blockSize;
|
|
|
|
const VkDeviceSize bytesPerLayer = blockCount.height * bytesPerRow;
|
|
|
|
const VkDeviceSize bytesTotal = blockCount.depth * bytesPerLayer;
|
|
|
|
|
2018-01-21 00:04:17 +01:00
|
|
|
const bool directCopy = ((bytesPerRow == pitchPerRow ) || (blockCount.height == 1))
|
|
|
|
&& ((bytesPerLayer == pitchPerLayer) || (blockCount.depth == 1));
|
2018-01-20 21:42:11 +01:00
|
|
|
|
|
|
|
if (directCopy) {
|
|
|
|
std::memcpy(dstData, srcData, bytesTotal);
|
|
|
|
} else {
|
|
|
|
for (uint32_t i = 0; i < blockCount.depth; i++) {
|
|
|
|
for (uint32_t j = 0; j < blockCount.height; j++) {
|
|
|
|
std::memcpy(
|
|
|
|
dstData + j * bytesPerRow,
|
|
|
|
srcData + j * pitchPerRow,
|
|
|
|
bytesPerRow);
|
|
|
|
}
|
|
|
|
|
|
|
|
srcData += pitchPerLayer;
|
|
|
|
dstData += bytesPerLayer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-20 13:08:50 +01:00
|
|
|
|
|
|
|
VkDeviceSize computeImageDataSize(VkFormat format, VkExtent3D extent) {
|
|
|
|
const DxvkFormatInfo* formatInfo = imageFormatInfo(format);
|
|
|
|
return formatInfo->elementSize * flattenImageExtent(computeBlockCount(extent, formatInfo->blockSize));
|
|
|
|
}
|
2018-09-01 16:49:24 +02:00
|
|
|
|
|
|
|
|
|
|
|
static VkColorComponentFlags remapComponentFlag(
|
|
|
|
VkColorComponentFlags mask,
|
|
|
|
VkComponentSwizzle swizzle,
|
|
|
|
VkColorComponentFlagBits identity) {
|
|
|
|
VkColorComponentFlags bit;
|
|
|
|
|
|
|
|
switch (swizzle) {
|
|
|
|
case VK_COMPONENT_SWIZZLE_IDENTITY: bit = identity; break;
|
|
|
|
case VK_COMPONENT_SWIZZLE_R: bit = VK_COLOR_COMPONENT_R_BIT; break;
|
|
|
|
case VK_COMPONENT_SWIZZLE_G: bit = VK_COLOR_COMPONENT_G_BIT; break;
|
|
|
|
case VK_COMPONENT_SWIZZLE_B: bit = VK_COLOR_COMPONENT_B_BIT; break;
|
|
|
|
case VK_COMPONENT_SWIZZLE_A: bit = VK_COLOR_COMPONENT_A_BIT; break;
|
|
|
|
default: bit = 0; /* SWIZZLE_ZERO, SWIZZLE_ONE */
|
|
|
|
}
|
|
|
|
|
|
|
|
return (mask & bit) ? identity : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkColorComponentFlags remapComponentMask(
|
|
|
|
VkColorComponentFlags mask,
|
|
|
|
VkComponentMapping mapping) {
|
|
|
|
VkColorComponentFlags result = 0;
|
|
|
|
result |= remapComponentFlag(mask, mapping.r, VK_COLOR_COMPONENT_R_BIT);
|
|
|
|
result |= remapComponentFlag(mask, mapping.g, VK_COLOR_COMPONENT_G_BIT);
|
|
|
|
result |= remapComponentFlag(mask, mapping.b, VK_COLOR_COMPONENT_B_BIT);
|
|
|
|
result |= remapComponentFlag(mask, mapping.a, VK_COLOR_COMPONENT_A_BIT);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static VkComponentSwizzle findComponentSwizzle(
|
|
|
|
VkComponentSwizzle swizzle,
|
|
|
|
VkComponentSwizzle identity,
|
|
|
|
VkComponentMapping mapping) {
|
|
|
|
if (identity == VK_COMPONENT_SWIZZLE_IDENTITY)
|
|
|
|
return VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
|
|
|
|
|
|
if (mapping.r == swizzle)
|
|
|
|
return VK_COMPONENT_SWIZZLE_R;
|
|
|
|
if (mapping.g == swizzle)
|
|
|
|
return VK_COMPONENT_SWIZZLE_G;
|
|
|
|
if (mapping.b == swizzle)
|
|
|
|
return VK_COMPONENT_SWIZZLE_B;
|
|
|
|
if (mapping.a == swizzle)
|
|
|
|
return VK_COMPONENT_SWIZZLE_A;
|
|
|
|
|
|
|
|
return VK_COMPONENT_SWIZZLE_ZERO;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkComponentMapping invertComponentMapping(VkComponentMapping mapping) {
|
|
|
|
VkComponentMapping result;
|
|
|
|
result.r = findComponentSwizzle(VK_COMPONENT_SWIZZLE_R, mapping.r, mapping);
|
|
|
|
result.g = findComponentSwizzle(VK_COMPONENT_SWIZZLE_G, mapping.g, mapping);
|
|
|
|
result.b = findComponentSwizzle(VK_COMPONENT_SWIZZLE_B, mapping.b, mapping);
|
|
|
|
result.a = findComponentSwizzle(VK_COMPONENT_SWIZZLE_A, mapping.a, mapping);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-09-01 17:53:45 +02:00
|
|
|
|
|
|
|
uint32_t getComponentIndex(
|
|
|
|
VkComponentSwizzle component,
|
|
|
|
uint32_t identity) {
|
|
|
|
switch (component) {
|
|
|
|
case VK_COMPONENT_SWIZZLE_R: return 0;
|
|
|
|
case VK_COMPONENT_SWIZZLE_G: return 1;
|
|
|
|
case VK_COMPONENT_SWIZZLE_B: return 2;
|
|
|
|
case VK_COMPONENT_SWIZZLE_A: return 3;
|
|
|
|
default: return identity; /* identity, zero, one */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-16 20:00:28 +01:00
|
|
|
|
2019-05-14 21:21:14 +02:00
|
|
|
VkClearColorValue swizzleClearColor(
|
|
|
|
VkClearColorValue color,
|
|
|
|
VkComponentMapping mapping) {
|
|
|
|
VkClearColorValue result;
|
|
|
|
auto swizzles = &mapping.r;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < 4; i++) {
|
|
|
|
uint32_t index = getComponentIndex(swizzles[i], i);
|
|
|
|
result.uint32[i] = color.uint32[index];
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-01-16 19:31:38 +01:00
|
|
|
bool isBlendConstantBlendFactor(VkBlendFactor factor) {
|
|
|
|
return factor == VK_BLEND_FACTOR_CONSTANT_COLOR
|
|
|
|
|| factor == VK_BLEND_FACTOR_CONSTANT_ALPHA
|
|
|
|
|| factor == VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR
|
|
|
|
|| factor == VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-11-16 20:00:28 +01:00
|
|
|
bool isDualSourceBlendFactor(VkBlendFactor factor) {
|
|
|
|
return factor == VK_BLEND_FACTOR_SRC1_COLOR
|
|
|
|
|| factor == VK_BLEND_FACTOR_SRC1_ALPHA
|
|
|
|
|| factor == VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR
|
|
|
|
|| factor == VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
|
|
|
|
}
|
|
|
|
|
2017-12-10 15:57:51 +01:00
|
|
|
}
|