1
0
mirror of https://github.com/EduApps-CDG/OpenDX synced 2024-12-30 09:45:37 +01:00
OpenDX/src/dxvk/dxvk_util.cpp
Philip Rebohle 4d4db6c683
[dxvk] Use void pointers for packImageData
Makes this function a bit less annoying to use.
2019-06-25 14:17:03 +02:00

187 lines
6.3 KiB
C++

#include <cstring>
#include "dxvk_format.h"
#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;
}
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;
}
void packImageData(
void* dstBytes,
const void* srcBytes,
VkExtent3D blockCount,
VkDeviceSize blockSize,
VkDeviceSize pitchPerRow,
VkDeviceSize pitchPerLayer) {
auto dstData = reinterpret_cast< char*>(dstBytes);
auto srcData = reinterpret_cast<const char*>(srcBytes);
const VkDeviceSize bytesPerRow = blockCount.width * blockSize;
const VkDeviceSize bytesPerLayer = blockCount.height * bytesPerRow;
const VkDeviceSize bytesTotal = blockCount.depth * bytesPerLayer;
const bool directCopy = ((bytesPerRow == pitchPerRow ) || (blockCount.height == 1))
&& ((bytesPerLayer == pitchPerLayer) || (blockCount.depth == 1));
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;
}
}
}
VkDeviceSize computeImageDataSize(VkFormat format, VkExtent3D extent) {
const DxvkFormatInfo* formatInfo = imageFormatInfo(format);
return formatInfo->elementSize * flattenImageExtent(computeBlockCount(extent, formatInfo->blockSize));
}
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;
}
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 */
}
}
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;
}
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;
}
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;
}
}