Skip to content

Commit

Permalink
[d3d9] Implement YV12 video format
Browse files Browse the repository at this point in the history
Needed for doitsujin#1726 otherwise it will upload dump that upload garbage in a YUV2 texture.
  • Loading branch information
misyltoad committed Aug 17, 2020
1 parent 89d36e1 commit 743f309
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/d3d9/d3d9_common_texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ namespace dxvk {

const uint32_t planeCount = m_mapping.ConversionFormatInfo.PlaneCount;

return planeCount
return std::min(planeCount, 2u)
* formatInfo.elementSize
* blockCount.width
* blockCount.height
Expand Down
9 changes: 9 additions & 0 deletions src/d3d9/d3d9_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,15 @@ namespace dxvk {
{ D3D9ConversionFormat_NV12, 2u, VK_FORMAT_B8G8R8A8_UNORM }
};

case D3D9Format::YV12: 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_YV12, 3u, VK_FORMAT_B8G8R8A8_UNORM }
};

case D3D9Format::RAWZ: return {}; // Unsupported

default:
Expand Down
1 change: 1 addition & 0 deletions src/d3d9/d3d9_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ namespace dxvk {
D3D9ConversionFormat_X8L8V8U8,
D3D9ConversionFormat_A2W10V10U10,
D3D9ConversionFormat_NV12,
D3D9ConversionFormat_YV12,
D3D9ConversionFormat_Count
};

Expand Down
6 changes: 6 additions & 0 deletions src/d3d9/d3d9_format_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <d3d9_convert_x8l8v8u8.h>
#include <d3d9_convert_a2w10v10u10.h>
#include <d3d9_convert_nv12.h>
#include <d3d9_convert_yv12.h>

namespace dxvk {

Expand Down Expand Up @@ -40,6 +41,10 @@ namespace dxvk {
ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcBuffer, VK_FORMAT_R16_UINT, 0, { 2u, 1u });
break;

case D3D9ConversionFormat_YV12:
ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcBuffer, VK_FORMAT_R8_UINT, 0, { 1u, 1u });
break;

case D3D9ConversionFormat_L6V5U5:
ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcBuffer, VK_FORMAT_R16_UINT, 0, { 1u, 1u });
break;
Expand Down Expand Up @@ -115,6 +120,7 @@ namespace dxvk {
m_shaders[D3D9ConversionFormat_X8L8V8U8] = InitShader(d3d9_convert_x8l8v8u8);
m_shaders[D3D9ConversionFormat_A2W10V10U10] = InitShader(d3d9_convert_a2w10v10u10);
m_shaders[D3D9ConversionFormat_NV12] = InitShader(d3d9_convert_nv12);
m_shaders[D3D9ConversionFormat_YV12] = InitShader(d3d9_convert_yv12);
}


Expand Down
3 changes: 2 additions & 1 deletion src/d3d9/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ d3d9_shaders = files([
'shaders/d3d9_convert_l6v5u5.comp',
'shaders/d3d9_convert_x8l8v8u8.comp',
'shaders/d3d9_convert_a2w10v10u10.comp',
'shaders/d3d9_convert_nv12.comp'
'shaders/d3d9_convert_nv12.comp',
'shaders/d3d9_convert_yv12.comp'
])

d3d9_src = [
Expand Down
58 changes: 58 additions & 0 deletions src/d3d9/shaders/d3d9_convert_yv12.comp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#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;

// Format is:
// YYYYYYYY...
// VVVV...
// UUUU...

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);

uint offset = thread_id.x
+ thread_id.y * pitch.x;

// Fetch a Y, luminance sample.
float y = fetchUnorm(src, offset) - (16 / 255.0);

// Go into the second plane to get a V, chroma sample
offset = (thread_id.x / 2)
+ (thread_id.y / 2) * (pitch.x / 2)
+ pitch.x * pitch.y;

float v = fetchUnorm(src, offset) - (128 / 255.0);

// Go into the third plane to get a U, chroma sample
offset += (pitch.x / 2) * (pitch.y / 2);
float u = fetchUnorm(src, offset) - (128 / 255.0);

// TODO: Is this the right color space?
vec4 color = convertBT_709(vec3(y, u, v));

imageStore(dst, thread_id.xy, color);
}
}

0 comments on commit 743f309

Please sign in to comment.