1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-20 10:54:16 +01:00

[d3d9] Implement L6V5U5 format via conversion

This commit is contained in:
Joshua Ashton 2020-02-24 06:39:25 +00:00
parent 419083f126
commit 7743276e1d
6 changed files with 120 additions and 2 deletions

View File

@ -129,7 +129,16 @@ namespace dxvk {
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_ONE }};
case D3D9Format::L6V5U5: return {}; // Unsupported
case D3D9Format::L6V5U5: return {
// Any PACK16 format will do...
VK_FORMAT_B5G6R5_UNORM_PACK16,
VK_FORMAT_UNDEFINED,
VK_IMAGE_ASPECT_COLOR_BIT,
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A },
{ D3D9ConversionFormat_L6V5U5, { 1u, 1u },
// Convert -> float (this is a mixed snorm and unorm type)
VK_FORMAT_R16G16B16A16_SFLOAT } };
case D3D9Format::X8L8V8U8: return {}; // Unsupported

View File

@ -131,6 +131,7 @@ namespace dxvk {
D3D9ConversionFormat_None = 0,
D3D9ConversionFormat_YUY2 = 1,
D3D9ConversionFormat_UYVY,
D3D9ConversionFormat_L6V5U5,
D3D9ConversionFormat_Count
};

View File

@ -1,6 +1,7 @@
#include "d3d9_format_helpers.h"
#include <d3d9_convert_yuy2_uyvy.h>
#include <d3d9_convert_l6v5u5.h>
namespace dxvk {
@ -22,12 +23,52 @@ namespace dxvk {
case D3D9ConversionFormat_YUY2:
case D3D9ConversionFormat_UYVY:
ConvertVideoFormat(conversionFormat, dstImage, dstSubresource, srcBuffer);
case D3D9ConversionFormat_L6V5U5:
ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcBuffer, VK_FORMAT_R16_UINT);
default:
Logger::warn("Unimplemented format conversion");
}
}
void D3D9FormatHelper::ConvertGenericFormat(
D3D9_CONVERSION_FORMAT_INFO videoFormat,
const Rc<DxvkImage>& dstImage,
VkImageSubresourceLayers dstSubresource,
const Rc<DxvkBuffer>& srcBuffer,
VkFormat bufferFormat) {
DxvkImageViewCreateInfo imageViewInfo;
imageViewInfo.type = VK_IMAGE_VIEW_TYPE_2D;
imageViewInfo.format = dstImage->info().format;
imageViewInfo.usage = VK_IMAGE_USAGE_STORAGE_BIT;
imageViewInfo.aspect = dstSubresource.aspectMask;
imageViewInfo.minLevel = dstSubresource.mipLevel;
imageViewInfo.numLevels = 1;
imageViewInfo.minLayer = dstSubresource.baseArrayLayer;
imageViewInfo.numLayers = dstSubresource.layerCount;
auto tmpImageView = m_device->createImageView(dstImage, imageViewInfo);
VkExtent3D imageExtent = dstImage->mipLevelExtent(dstSubresource.mipLevel);
DxvkBufferViewCreateInfo bufferViewInfo;
bufferViewInfo.format = bufferFormat;
bufferViewInfo.rangeOffset = 0;
bufferViewInfo.rangeLength = srcBuffer->info().size;
auto tmpBufferView = m_device->createBufferView(srcBuffer, bufferViewInfo);
m_context->bindResourceView(BindingIds::Image, tmpImageView, nullptr);
m_context->bindResourceView(BindingIds::Buffer, nullptr, tmpBufferView);
m_context->bindShader(VK_SHADER_STAGE_COMPUTE_BIT, m_shaders[videoFormat.FormatType]);
m_context->pushConstants(0, sizeof(VkExtent2D), &imageExtent);
m_context->dispatch(
(imageExtent.width / 8) + (imageExtent.width % 8),
(imageExtent.height / 8) + (imageExtent.height % 8),
1);
m_context->flushCommandList();
}
void D3D9FormatHelper::ConvertVideoFormat(
D3D9_CONVERSION_FORMAT_INFO videoFormat,
const Rc<DxvkImage>& dstImage,
@ -76,6 +117,7 @@ namespace dxvk {
void D3D9FormatHelper::InitShaders() {
m_shaders[D3D9ConversionFormat_YUY2] = InitShader(d3d9_convert_yuy2_uyvy);
m_shaders[D3D9ConversionFormat_UYVY] = m_shaders[D3D9ConversionFormat_YUY2];
m_shaders[D3D9ConversionFormat_L6V5U5] = InitShader(d3d9_convert_l6v5u5);
}

View File

@ -21,6 +21,13 @@ namespace dxvk {
private:
void ConvertGenericFormat(
D3D9_CONVERSION_FORMAT_INFO videoFormat,
const Rc<DxvkImage>& dstImage,
VkImageSubresourceLayers dstSubresource,
const Rc<DxvkBuffer>& srcBuffer,
VkFormat bufferFormat);
void ConvertVideoFormat(
D3D9_CONVERSION_FORMAT_INFO videoFormat,
const Rc<DxvkImage>& dstImage,

View File

@ -3,7 +3,8 @@ d3d9_res = wrc_generator.process('version.rc')
d3d9_shaders = files([
'shaders/d3d9_presenter_frag.frag',
'shaders/d3d9_presenter_vert.vert',
'shaders/d3d9_convert_yuy2_uyvy.comp'
'shaders/d3d9_convert_yuy2_uyvy.comp',
'shaders/d3d9_convert_l6v5u5.comp'
])
d3d9_src = [

View File

@ -0,0 +1,58 @@
#version 450
#extension GL_EXT_shader_16bit_storage : enable
layout(
local_size_x = 8,
local_size_y = 8,
local_size_z = 1) in;
layout(binding = 0)
writeonly uniform image2D dst;
layout(binding = 1)
readonly buffer _buffer_t {
uint16_t data[];
} src;
layout(push_constant)
uniform u_info_t {
uvec2 extent;
} u_info;
float unormalize(uint value, int bits) {
const int range = (1 << bits) - 1;
return float(value) / float(range);
}
float snormalize(int value, int bits) {
const int range = (1 << (bits - 1)) - 1;
// Min because, -32 and -31 map to -1.0f, and we
// divide by 31.
return max(float(value) / float(range), -1.0f);
}
void main() {
ivec3 thread_id = ivec3(gl_GlobalInvocationID);
if (all(lessThan(thread_id.xy, u_info.extent))) {
uint offset = thread_id.x
+ thread_id.y * u_info.extent.x;
uint value = uint(src.data[offset]);
// Sign-extend magic!
int u5 = bitfieldExtract(int (value), 0, 5);
int v5 = bitfieldExtract(int (value), 5, 5);
uint l6 = bitfieldExtract(uint(value), 10, 6);
vec4 color = vec4(
snormalize(u5, 5),
snormalize(v5, 5),
unormalize(l6, 6),
1.0f);
imageStore(dst, thread_id.xy, color);
}
}