mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-15 07:29:17 +01:00
[d3d9] Implement NV12 format conversion
This commit is contained in:
parent
32c1a4e2b8
commit
2bf9f298af
@ -190,7 +190,10 @@ namespace dxvk {
|
|||||||
const VkExtent3D blockCount = util::computeBlockCount(
|
const VkExtent3D blockCount = util::computeBlockCount(
|
||||||
mipExtent, formatInfo.blockSize);
|
mipExtent, formatInfo.blockSize);
|
||||||
|
|
||||||
|
const uint32_t planeCount = m_mapping.ConversionFormatInfo.MacroPixelSize.depth;
|
||||||
|
|
||||||
return formatInfo.elementSize
|
return formatInfo.elementSize
|
||||||
|
* planeCount
|
||||||
* blockCount.width
|
* blockCount.width
|
||||||
* blockCount.height
|
* blockCount.height
|
||||||
* blockCount.depth;
|
* blockCount.depth;
|
||||||
|
@ -406,6 +406,15 @@ namespace dxvk {
|
|||||||
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R,
|
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R,
|
||||||
VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R }};
|
VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R }};
|
||||||
|
|
||||||
|
case D3D9Format::NV12: return {
|
||||||
|
VK_FORMAT_R8_UNORM,
|
||||||
|
VK_FORMAT_UNDEFINED,
|
||||||
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
{ VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
|
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY },
|
||||||
|
{ D3D9ConversionFormat_NV12, { 1u, 1u, 2u }, VK_FORMAT_B8G8R8A8_UNORM }
|
||||||
|
};
|
||||||
|
|
||||||
case D3D9Format::RAWZ: return {}; // Unsupported
|
case D3D9Format::RAWZ: return {}; // Unsupported
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -134,12 +134,13 @@ namespace dxvk {
|
|||||||
D3D9ConversionFormat_L6V5U5,
|
D3D9ConversionFormat_L6V5U5,
|
||||||
D3D9ConversionFormat_X8L8V8U8,
|
D3D9ConversionFormat_X8L8V8U8,
|
||||||
D3D9ConversionFormat_A2W10V10U10,
|
D3D9ConversionFormat_A2W10V10U10,
|
||||||
|
D3D9ConversionFormat_NV12,
|
||||||
D3D9ConversionFormat_Count
|
D3D9ConversionFormat_Count
|
||||||
};
|
};
|
||||||
|
|
||||||
struct D3D9_CONVERSION_FORMAT_INFO {
|
struct D3D9_CONVERSION_FORMAT_INFO {
|
||||||
D3D9ConversionFormat FormatType = D3D9ConversionFormat_None;
|
D3D9ConversionFormat FormatType = D3D9ConversionFormat_None;
|
||||||
VkExtent2D MacroPixelSize = { 1u, 1u };
|
VkExtent3D MacroPixelSize = { 1u, 1u, 1u };
|
||||||
VkFormat FormatColor = VK_FORMAT_UNDEFINED;
|
VkFormat FormatColor = VK_FORMAT_UNDEFINED;
|
||||||
VkFormat FormatSrgb = VK_FORMAT_UNDEFINED;
|
VkFormat FormatSrgb = VK_FORMAT_UNDEFINED;
|
||||||
};
|
};
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <d3d9_convert_l6v5u5.h>
|
#include <d3d9_convert_l6v5u5.h>
|
||||||
#include <d3d9_convert_x8l8v8u8.h>
|
#include <d3d9_convert_x8l8v8u8.h>
|
||||||
#include <d3d9_convert_a2w10v10u10.h>
|
#include <d3d9_convert_a2w10v10u10.h>
|
||||||
|
#include <d3d9_convert_nv12.h>
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
@ -35,6 +36,10 @@ namespace dxvk {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case D3D9ConversionFormat_NV12:
|
||||||
|
ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcBuffer, VK_FORMAT_R8_UINT, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
case D3D9ConversionFormat_L6V5U5:
|
case D3D9ConversionFormat_L6V5U5:
|
||||||
ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcBuffer, VK_FORMAT_R16_UINT, 0);
|
ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcBuffer, VK_FORMAT_R16_UINT, 0);
|
||||||
break;
|
break;
|
||||||
@ -108,6 +113,7 @@ namespace dxvk {
|
|||||||
m_shaders[D3D9ConversionFormat_L6V5U5] = InitShader(d3d9_convert_l6v5u5);
|
m_shaders[D3D9ConversionFormat_L6V5U5] = InitShader(d3d9_convert_l6v5u5);
|
||||||
m_shaders[D3D9ConversionFormat_X8L8V8U8] = InitShader(d3d9_convert_x8l8v8u8);
|
m_shaders[D3D9ConversionFormat_X8L8V8U8] = InitShader(d3d9_convert_x8l8v8u8);
|
||||||
m_shaders[D3D9ConversionFormat_A2W10V10U10] = InitShader(d3d9_convert_a2w10v10u10);
|
m_shaders[D3D9ConversionFormat_A2W10V10U10] = InitShader(d3d9_convert_a2w10v10u10);
|
||||||
|
m_shaders[D3D9ConversionFormat_NV12] = InitShader(d3d9_convert_nv12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,7 +6,8 @@ d3d9_shaders = files([
|
|||||||
'shaders/d3d9_convert_yuy2_uyvy.comp',
|
'shaders/d3d9_convert_yuy2_uyvy.comp',
|
||||||
'shaders/d3d9_convert_l6v5u5.comp',
|
'shaders/d3d9_convert_l6v5u5.comp',
|
||||||
'shaders/d3d9_convert_x8l8v8u8.comp',
|
'shaders/d3d9_convert_x8l8v8u8.comp',
|
||||||
'shaders/d3d9_convert_a2w10v10u10.comp'
|
'shaders/d3d9_convert_a2w10v10u10.comp',
|
||||||
|
'shaders/d3d9_convert_nv12.comp'
|
||||||
])
|
])
|
||||||
|
|
||||||
d3d9_src = [
|
d3d9_src = [
|
||||||
|
@ -27,3 +27,13 @@ vec4 convertYUV(vec3 yuv) {
|
|||||||
|
|
||||||
return vec4(clamp(value, 0, 1), 1);
|
return vec4(clamp(value, 0, 1), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mat3x3 g_bt703_to_rgb = {
|
||||||
|
{ 1.164, 0, 1.793 },
|
||||||
|
{ 1.164, -0.213, -0.533 },
|
||||||
|
{ 1.164, 2.112, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
vec4 convertBT_703(vec3 cde) {
|
||||||
|
return vec4(clamp(cde * g_bt703_to_rgb, 0, 1), 1);
|
||||||
|
}
|
||||||
|
56
src/d3d9/shaders/d3d9_convert_nv12.comp
Normal file
56
src/d3d9/shaders/d3d9_convert_nv12.comp
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#version 450
|
||||||
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
#include "d3d9_convert_common.h"
|
||||||
|
|
||||||
|
layout(
|
||||||
|
local_size_x = 8,
|
||||||
|
local_size_y = 8,
|
||||||
|
local_size_z = 1) in;
|
||||||
|
|
||||||
|
layout(binding = 0)
|
||||||
|
writeonly uniform image2D dst;
|
||||||
|
|
||||||
|
layout(binding = 1) uniform usamplerBuffer src;
|
||||||
|
|
||||||
|
layout(push_constant)
|
||||||
|
uniform u_info_t {
|
||||||
|
uvec2 extent;
|
||||||
|
} u_info;
|
||||||
|
|
||||||
|
float fetchUnorm(usamplerBuffer source, uint offset) {
|
||||||
|
return unpackUnorm(texelFetch(src, int(offset)).r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
ivec3 thread_id = ivec3(gl_GlobalInvocationID);
|
||||||
|
|
||||||
|
if (all(lessThan(thread_id.xy, u_info.extent))) {
|
||||||
|
uvec2 pitch = uvec2(u_info.extent.x, u_info.extent.y);
|
||||||
|
|
||||||
|
// Format is:
|
||||||
|
// YYYYYYYYYYYYYYY...
|
||||||
|
// UVUVUVUVUVUVUVU...
|
||||||
|
uint offset = thread_id.x
|
||||||
|
+ thread_id.y * pitch.x;
|
||||||
|
|
||||||
|
float c0 = fetchUnorm(src, offset) - (16 / 255.0);
|
||||||
|
|
||||||
|
// Floor .x to the nearest 2, because
|
||||||
|
// UV data is in WORDs, and we want to get the color
|
||||||
|
// for this pixel.
|
||||||
|
// Then divide thread_id.y by 2 because the macropixel
|
||||||
|
// layout for chroma data is [2, 2].
|
||||||
|
offset = (thread_id.x / 2) * 2
|
||||||
|
+ thread_id.y / 2 * pitch.x
|
||||||
|
+ pitch.x * pitch.y;
|
||||||
|
|
||||||
|
float u = fetchUnorm(src, offset) - (128 / 255.0);
|
||||||
|
float v = fetchUnorm(src, offset + 1) - (128 / 255.0);
|
||||||
|
|
||||||
|
// The NV12 format seems to use the BT.703 color space.
|
||||||
|
vec4 color0 = convertBT_703(vec3(c0, u, v));
|
||||||
|
|
||||||
|
imageStore(dst, thread_id.xy, color0);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user