mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-26 07:17:23 +00:00
[host] added YUV420 output support
This commit is contained in:
parent
2a03d1c4a9
commit
e515cdc8dd
@ -27,7 +27,7 @@ typedef enum FrameType
|
|||||||
{
|
{
|
||||||
FRAME_TYPE_INVALID ,
|
FRAME_TYPE_INVALID ,
|
||||||
FRAME_TYPE_ARGB , // ABGR interleaved: A,R,G,B 32bpp
|
FRAME_TYPE_ARGB , // ABGR interleaved: A,R,G,B 32bpp
|
||||||
FRAME_TYPE_NV12 , // NV12
|
FRAME_TYPE_YUV420 , // YUV420
|
||||||
FRAME_TYPE_H264 , // H264 compressed
|
FRAME_TYPE_H264 , // H264 compressed
|
||||||
FRAME_TYPE_MAX , // sentinel value
|
FRAME_TYPE_MAX , // sentinel value
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@ DXGI::DXGI() :
|
|||||||
m_device(),
|
m_device(),
|
||||||
m_deviceContext(),
|
m_deviceContext(),
|
||||||
m_dup(),
|
m_dup(),
|
||||||
m_texture(),
|
|
||||||
m_pointer(NULL)
|
m_pointer(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -153,7 +152,7 @@ bool DXGI::Initialize(CaptureOptions * options)
|
|||||||
for(CaptureOptions::const_iterator it = m_options->cbegin(); it != m_options->cend(); ++it)
|
for(CaptureOptions::const_iterator it = m_options->cbegin(); it != m_options->cend(); ++it)
|
||||||
{
|
{
|
||||||
if (_stricmp(*it, "h264" ) == 0) m_frameType = FRAME_TYPE_H264;
|
if (_stricmp(*it, "h264" ) == 0) m_frameType = FRAME_TYPE_H264;
|
||||||
if (_stricmp(*it, "nv12") == 0) m_frameType = FRAME_TYPE_NV12;
|
if (_stricmp(*it, "yuv420") == 0) m_frameType = FRAME_TYPE_YUV420;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_frameType == FRAME_TYPE_H264)
|
if (m_frameType == FRAME_TYPE_H264)
|
||||||
@ -163,7 +162,7 @@ bool DXGI::Initialize(CaptureOptions * options)
|
|||||||
switch (m_frameType)
|
switch (m_frameType)
|
||||||
{
|
{
|
||||||
case FRAME_TYPE_ARGB : ok = InitRawCapture (); break;
|
case FRAME_TYPE_ARGB : ok = InitRawCapture (); break;
|
||||||
case FRAME_TYPE_NV12: ok = InitNV12Capture(); break;
|
case FRAME_TYPE_YUV420: ok = InitYUV420Capture(); break;
|
||||||
case FRAME_TYPE_H264 : ok = InitH264Capture (); break;
|
case FRAME_TYPE_H264 : ok = InitH264Capture (); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +220,7 @@ bool DXGI::InitRawCapture()
|
|||||||
texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||||
texDesc.MiscFlags = 0;
|
texDesc.MiscFlags = 0;
|
||||||
|
|
||||||
HRESULT status = m_device->CreateTexture2D(&texDesc, NULL, &m_texture);
|
HRESULT status = m_device->CreateTexture2D(&texDesc, NULL, &m_texture[0]);
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
DEBUG_WINERROR("Failed to create texture", status);
|
DEBUG_WINERROR("Failed to create texture", status);
|
||||||
@ -231,9 +230,11 @@ bool DXGI::InitRawCapture()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DXGI::InitNV12Capture()
|
bool DXGI::InitYUV420Capture()
|
||||||
{
|
{
|
||||||
|
HRESULT status;
|
||||||
D3D11_TEXTURE2D_DESC texDesc;
|
D3D11_TEXTURE2D_DESC texDesc;
|
||||||
|
|
||||||
ZeroMemory(&texDesc, sizeof(texDesc));
|
ZeroMemory(&texDesc, sizeof(texDesc));
|
||||||
texDesc.Width = m_width;
|
texDesc.Width = m_width;
|
||||||
texDesc.Height = m_height;
|
texDesc.Height = m_height;
|
||||||
@ -242,12 +243,29 @@ bool DXGI::InitNV12Capture()
|
|||||||
texDesc.SampleDesc.Count = 1;
|
texDesc.SampleDesc.Count = 1;
|
||||||
texDesc.SampleDesc.Quality = 0;
|
texDesc.SampleDesc.Quality = 0;
|
||||||
texDesc.Usage = D3D11_USAGE_STAGING;
|
texDesc.Usage = D3D11_USAGE_STAGING;
|
||||||
texDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
texDesc.Format = DXGI_FORMAT_R8_UNORM;
|
||||||
texDesc.BindFlags = 0;
|
texDesc.BindFlags = 0;
|
||||||
texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||||
texDesc.MiscFlags = 0;
|
texDesc.MiscFlags = 0;
|
||||||
|
|
||||||
HRESULT status = m_device->CreateTexture2D(&texDesc, NULL, &m_texture);
|
status = m_device->CreateTexture2D(&texDesc, NULL, &m_texture[0]);
|
||||||
|
if (FAILED(status))
|
||||||
|
{
|
||||||
|
DEBUG_WINERROR("Failed to create texture", status);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
texDesc.Width /= 2;
|
||||||
|
texDesc.Height /= 2;
|
||||||
|
|
||||||
|
status = m_device->CreateTexture2D(&texDesc, NULL, &m_texture[1]);
|
||||||
|
if (FAILED(status))
|
||||||
|
{
|
||||||
|
DEBUG_WINERROR("Failed to create texture", status);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = m_device->CreateTexture2D(&texDesc, NULL, &m_texture[2]);
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
DEBUG_WINERROR("Failed to create texture", status);
|
DEBUG_WINERROR("Failed to create texture", status);
|
||||||
@ -255,7 +273,7 @@ bool DXGI::InitNV12Capture()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_textureConverter = new TextureConverter();
|
m_textureConverter = new TextureConverter();
|
||||||
if (!m_textureConverter->Initialize(m_deviceContext, m_device, m_width, m_height, DXGI_FORMAT_NV12))
|
if (!m_textureConverter->Initialize(m_deviceContext, m_device, m_width, m_height, FRAME_TYPE_YUV420))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -264,7 +282,7 @@ bool DXGI::InitNV12Capture()
|
|||||||
bool DXGI::InitH264Capture()
|
bool DXGI::InitH264Capture()
|
||||||
{
|
{
|
||||||
m_textureConverter = new TextureConverter();
|
m_textureConverter = new TextureConverter();
|
||||||
if (!m_textureConverter->Initialize(m_deviceContext, m_device, m_width, m_height, DXGI_FORMAT_NV12))
|
if (!m_textureConverter->Initialize(m_deviceContext, m_device, m_width, m_height, FRAME_TYPE_YUV420))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_h264 = new MFT::H264();
|
m_h264 = new MFT::H264();
|
||||||
@ -297,13 +315,9 @@ void DXGI::DeInitialize()
|
|||||||
m_pointerBufSize = 0;
|
m_pointerBufSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_surfaceMapped)
|
SafeRelease(&m_texture[0]);
|
||||||
{
|
SafeRelease(&m_texture[1]);
|
||||||
m_deviceContext->Unmap(m_texture, 0);
|
SafeRelease(&m_texture[2]);
|
||||||
m_surfaceMapped = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SafeRelease(&m_texture);
|
|
||||||
SafeRelease(&m_dup);
|
SafeRelease(&m_dup);
|
||||||
SafeRelease(&m_output);
|
SafeRelease(&m_output);
|
||||||
SafeRelease(&m_deviceContext);
|
SafeRelease(&m_deviceContext);
|
||||||
@ -494,49 +508,44 @@ GrabStatus Capture::DXGI::ReleaseFrame()
|
|||||||
GrabStatus Capture::DXGI::GrabFrameRaw(FrameInfo & frame, struct CursorInfo & cursor)
|
GrabStatus Capture::DXGI::GrabFrameRaw(FrameInfo & frame, struct CursorInfo & cursor)
|
||||||
{
|
{
|
||||||
GrabStatus result;
|
GrabStatus result;
|
||||||
ID3D11Texture2DPtr src;
|
ID3D11Texture2DPtr texture;
|
||||||
bool timeout;
|
bool timeout;
|
||||||
|
D3D11_MAPPED_SUBRESOURCE mapping;
|
||||||
|
|
||||||
result = GrabFrameTexture(frame, cursor, src, timeout);
|
result = GrabFrameTexture(frame, cursor, texture, timeout);
|
||||||
if (timeout)
|
if (timeout)
|
||||||
return GRAB_STATUS_TIMEOUT;
|
return GRAB_STATUS_TIMEOUT;
|
||||||
|
|
||||||
if (result != GRAB_STATUS_OK)
|
if (result != GRAB_STATUS_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (m_surfaceMapped)
|
m_deviceContext->CopyResource(m_texture[0], texture);
|
||||||
{
|
SafeRelease(&texture);
|
||||||
m_deviceContext->Unmap(m_texture, 0);
|
|
||||||
m_surfaceMapped = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_deviceContext->CopyResource(m_texture, src);
|
|
||||||
SafeRelease(&src);
|
|
||||||
|
|
||||||
result = ReleaseFrame();
|
result = ReleaseFrame();
|
||||||
if (result != GRAB_STATUS_OK)
|
if (result != GRAB_STATUS_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
HRESULT status;
|
HRESULT status;
|
||||||
status = m_deviceContext->Map(m_texture, 0, D3D11_MAP_READ, 0, &m_mapping);
|
status = m_deviceContext->Map(m_texture[0], 0, D3D11_MAP_READ, 0, &mapping);
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
DEBUG_WINERROR("Failed to map the texture", status);
|
DEBUG_WINERROR("Failed to map the texture", status);
|
||||||
DeInitialize();
|
DeInitialize();
|
||||||
return GRAB_STATUS_ERROR;
|
return GRAB_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
m_surfaceMapped = true;
|
|
||||||
|
|
||||||
frame.pitch = m_mapping.RowPitch;
|
frame.pitch = mapping.RowPitch;
|
||||||
frame.stride = m_mapping.RowPitch >> 2;
|
frame.stride = mapping.RowPitch >> 2;
|
||||||
|
|
||||||
const unsigned int size = m_height * m_mapping.RowPitch;
|
const unsigned int size = m_height * mapping.RowPitch;
|
||||||
memcpySSE(frame.buffer, m_mapping.pData, LG_MIN(size, frame.bufferSize));
|
memcpySSE(frame.buffer, mapping.pData, LG_MIN(size, frame.bufferSize));
|
||||||
|
m_deviceContext->Unmap(m_texture[0], 0);
|
||||||
|
|
||||||
return GRAB_STATUS_OK;
|
return GRAB_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrabStatus Capture::DXGI::GrabFrameNV12(struct FrameInfo & frame, struct CursorInfo & cursor)
|
GrabStatus Capture::DXGI::GrabFrameYUV420(struct FrameInfo & frame, struct CursorInfo & cursor)
|
||||||
{
|
{
|
||||||
GrabStatus result;
|
GrabStatus result;
|
||||||
ID3D11Texture2DPtr texture;
|
ID3D11Texture2DPtr texture;
|
||||||
@ -549,46 +558,63 @@ GrabStatus Capture::DXGI::GrabFrameNV12(struct FrameInfo & frame, struct CursorI
|
|||||||
if (result != GRAB_STATUS_OK)
|
if (result != GRAB_STATUS_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (!m_textureConverter->Convert(texture))
|
TextureList planes;
|
||||||
|
if (!m_textureConverter->Convert(texture, planes))
|
||||||
{
|
{
|
||||||
SafeRelease(&texture);
|
SafeRelease(&texture);
|
||||||
return GRAB_STATUS_ERROR;
|
return GRAB_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_surfaceMapped)
|
|
||||||
{
|
|
||||||
m_deviceContext->Unmap(m_texture, 0);
|
|
||||||
m_surfaceMapped = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_deviceContext->CopyResource(m_texture, texture);
|
|
||||||
SafeRelease(&texture);
|
SafeRelease(&texture);
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
ID3D11Texture2DPtr t = planes.at(i);
|
||||||
|
m_deviceContext->CopyResource(m_texture[i], planes.at(i));
|
||||||
|
SafeRelease(&t);
|
||||||
|
}
|
||||||
|
|
||||||
result = ReleaseFrame();
|
result = ReleaseFrame();
|
||||||
if (result != GRAB_STATUS_OK)
|
if (result != GRAB_STATUS_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
uint8_t * data = (uint8_t *)frame.buffer;
|
||||||
|
size_t remain = frame.bufferSize;
|
||||||
|
for(int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
HRESULT status;
|
HRESULT status;
|
||||||
status = m_deviceContext->Map(m_texture, 0, D3D11_MAP_READ, 0, &m_mapping);
|
D3D11_MAPPED_SUBRESOURCE mapping;
|
||||||
|
|
||||||
|
status = m_deviceContext->Map(m_texture[i], 0, D3D11_MAP_READ, 0, &mapping);
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
DEBUG_WINERROR("Failed to map the texture", status);
|
DEBUG_WINERROR("Failed to map the texture", status);
|
||||||
DeInitialize();
|
DeInitialize();
|
||||||
return GRAB_STATUS_ERROR;
|
return GRAB_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
m_surfaceMapped = true;
|
|
||||||
|
|
||||||
frame.pitch = m_mapping.RowPitch;
|
const unsigned int size = m_height * mapping.RowPitch;
|
||||||
frame.stride = m_mapping.RowPitch >> 2;
|
if (size > remain)
|
||||||
|
{
|
||||||
|
m_deviceContext->Unmap(m_texture[i], 0);
|
||||||
|
DEBUG_ERROR("Too much data to fit in buffer");
|
||||||
|
return GRAB_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
const unsigned int size = m_height * m_mapping.RowPitch;
|
memcpySSE(data, mapping.pData, size);
|
||||||
memcpySSE(frame.buffer, m_mapping.pData, LG_MIN(size, frame.bufferSize));
|
data += size;
|
||||||
|
remain -= size;
|
||||||
|
m_deviceContext->Unmap(m_texture[i], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
frame.pitch = m_width;
|
||||||
|
frame.stride = m_width;
|
||||||
return GRAB_STATUS_OK;
|
return GRAB_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrabStatus Capture::DXGI::GrabFrameH264(struct FrameInfo & frame, struct CursorInfo & cursor)
|
GrabStatus Capture::DXGI::GrabFrameH264(struct FrameInfo & frame, struct CursorInfo & cursor)
|
||||||
{
|
{
|
||||||
|
return GRAB_STATUS_ERROR;
|
||||||
|
#if 0
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
unsigned int events = m_h264->Process();
|
unsigned int events = m_h264->Process();
|
||||||
@ -631,6 +657,7 @@ GrabStatus Capture::DXGI::GrabFrameH264(struct FrameInfo & frame, struct CursorI
|
|||||||
return GRAB_STATUS_OK;
|
return GRAB_STATUS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
GrabStatus DXGI::GrabFrame(struct FrameInfo & frame, struct CursorInfo & cursor)
|
GrabStatus DXGI::GrabFrame(struct FrameInfo & frame, struct CursorInfo & cursor)
|
||||||
@ -640,7 +667,7 @@ GrabStatus DXGI::GrabFrame(struct FrameInfo & frame, struct CursorInfo & cursor)
|
|||||||
|
|
||||||
switch (m_frameType)
|
switch (m_frameType)
|
||||||
{
|
{
|
||||||
case FRAME_TYPE_NV12: return GrabFrameNV12(frame, cursor);
|
case FRAME_TYPE_YUV420: return GrabFrameYUV420(frame, cursor);
|
||||||
case FRAME_TYPE_H264 : return GrabFrameH264 (frame, cursor);
|
case FRAME_TYPE_H264 : return GrabFrameH264 (frame, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,13 +60,13 @@ namespace Capture
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool InitRawCapture();
|
bool InitRawCapture();
|
||||||
bool InitNV12Capture();
|
bool InitYUV420Capture();
|
||||||
bool InitH264Capture();
|
bool InitH264Capture();
|
||||||
|
|
||||||
GrabStatus GrabFrameTexture(struct FrameInfo & frame, struct CursorInfo & cursor, ID3D11Texture2DPtr & texture, bool & timeout);
|
GrabStatus GrabFrameTexture(struct FrameInfo & frame, struct CursorInfo & cursor, ID3D11Texture2DPtr & texture, bool & timeout);
|
||||||
GrabStatus ReleaseFrame();
|
GrabStatus ReleaseFrame();
|
||||||
GrabStatus GrabFrameRaw (struct FrameInfo & frame, struct CursorInfo & cursor);
|
GrabStatus GrabFrameRaw (struct FrameInfo & frame, struct CursorInfo & cursor);
|
||||||
GrabStatus GrabFrameNV12 (struct FrameInfo & frame, struct CursorInfo & cursor);
|
GrabStatus GrabFrameYUV420 (struct FrameInfo & frame, struct CursorInfo & cursor);
|
||||||
GrabStatus GrabFrameH264 (struct FrameInfo & frame, struct CursorInfo & cursor);
|
GrabStatus GrabFrameH264 (struct FrameInfo & frame, struct CursorInfo & cursor);
|
||||||
|
|
||||||
CaptureOptions * m_options;
|
CaptureOptions * m_options;
|
||||||
@ -83,9 +83,7 @@ namespace Capture
|
|||||||
IDXGIOutput1Ptr m_output;
|
IDXGIOutput1Ptr m_output;
|
||||||
IDXGIOutputDuplicationPtr m_dup;
|
IDXGIOutputDuplicationPtr m_dup;
|
||||||
bool m_releaseFrame;
|
bool m_releaseFrame;
|
||||||
ID3D11Texture2DPtr m_texture;
|
ID3D11Texture2DPtr m_texture[3];
|
||||||
D3D11_MAPPED_SUBRESOURCE m_mapping;
|
|
||||||
bool m_surfaceMapped;
|
|
||||||
TextureConverter * m_textureConverter;
|
TextureConverter * m_textureConverter;
|
||||||
MFT::H264 * m_h264;
|
MFT::H264 * m_h264;
|
||||||
|
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
Texture2D texTexture;
|
|
||||||
SamplerState texSampler;
|
|
||||||
|
|
||||||
struct VS
|
|
||||||
{
|
|
||||||
float4 pos : SV_Position;
|
|
||||||
float2 tex : TEXCOORD;
|
|
||||||
};
|
|
||||||
|
|
||||||
float4 RGBtoYUV(float4 rgba)
|
|
||||||
{
|
|
||||||
float4 yuva;
|
|
||||||
yuva.r = rgba.r * 0.2126 + 0.7152 * rgba.g + 0.0722 * rgba.b;
|
|
||||||
yuva.g = (rgba.b - yuva.r) / 1.8556;
|
|
||||||
yuva.b = (rgba.r - yuva.r) / 1.5748;
|
|
||||||
yuva.a = rgba.a;
|
|
||||||
yuva.gb += 0.5;
|
|
||||||
return yuva;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 main(VS input) : SV_TARGET
|
|
||||||
{
|
|
||||||
const float4 rgba = texTexture.Sample(texSampler, input.tex);
|
|
||||||
const float4 yuva = RGBtoYUV(rgba);
|
|
||||||
return yuva;
|
|
||||||
}
|
|
13
host/Shaders/Pixel.hlsl
Normal file
13
host/Shaders/Pixel.hlsl
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
Texture2D texTexture;
|
||||||
|
SamplerState texSampler;
|
||||||
|
|
||||||
|
struct VS
|
||||||
|
{
|
||||||
|
float4 pos : SV_Position;
|
||||||
|
float2 tex : TEXCOORD;
|
||||||
|
};
|
||||||
|
|
||||||
|
float4 main(VS input): SV_Target
|
||||||
|
{
|
||||||
|
return texTexture.Sample(texSampler, input.tex);
|
||||||
|
}
|
31
host/Shaders/RGBtoYUV.hlsl
Normal file
31
host/Shaders/RGBtoYUV.hlsl
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
Texture2D texTexture;
|
||||||
|
SamplerState texSampler;
|
||||||
|
|
||||||
|
struct VS
|
||||||
|
{
|
||||||
|
float4 pos : SV_Position;
|
||||||
|
float2 tex : TEXCOORD;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OUT
|
||||||
|
{
|
||||||
|
float4 y: SV_TARGET0;
|
||||||
|
float4 u: SV_TARGET1;
|
||||||
|
float4 v: SV_TARGET2;
|
||||||
|
};
|
||||||
|
|
||||||
|
OUT main(VS input)
|
||||||
|
{
|
||||||
|
OUT o;
|
||||||
|
const float4 rgba = texTexture.Sample(texSampler, input.tex);
|
||||||
|
|
||||||
|
o.y.gba = 0.0f;
|
||||||
|
o.u.gba = 0.0f;
|
||||||
|
o.v.gba = 0.0f;
|
||||||
|
|
||||||
|
o.y.r = rgba.r * 0.2126 + 0.7152 * rgba.g + 0.0722 * rgba.b;
|
||||||
|
o.u.r = (rgba.b - o.y.r) / 1.8556;
|
||||||
|
o.v.r = (rgba.r - o.y.r) / 1.5748;
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
@ -21,7 +21,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "common\debug.h"
|
#include "common\debug.h"
|
||||||
|
|
||||||
#include "Shaders\Vertex.h"
|
#include "Shaders\Vertex.h"
|
||||||
#include "Shaders\BGRAtoNV12.h"
|
#include "Shaders\Pixel.h"
|
||||||
|
#include "Shaders\RGBtoYUV.h"
|
||||||
|
|
||||||
TextureConverter::TextureConverter()
|
TextureConverter::TextureConverter()
|
||||||
{
|
{
|
||||||
@ -37,12 +38,12 @@ bool TextureConverter::Initialize(
|
|||||||
ID3D11DevicePtr device,
|
ID3D11DevicePtr device,
|
||||||
const unsigned int width,
|
const unsigned int width,
|
||||||
const unsigned int height,
|
const unsigned int height,
|
||||||
DXGI_FORMAT format
|
FrameType format
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
HRESULT result;
|
HRESULT result;
|
||||||
D3D11_TEXTURE2D_DESC texDesc;
|
D3D11_TEXTURE2D_DESC texDesc;
|
||||||
D3D11_RENDER_TARGET_VIEW_DESC viewDesc;
|
D3D11_RENDER_TARGET_VIEW_DESC targetDesc;
|
||||||
D3D11_SHADER_RESOURCE_VIEW_DESC shaderDesc;
|
D3D11_SHADER_RESOURCE_VIEW_DESC shaderDesc;
|
||||||
D3D11_SAMPLER_DESC samplerDesc;
|
D3D11_SAMPLER_DESC samplerDesc;
|
||||||
|
|
||||||
@ -52,10 +53,21 @@ bool TextureConverter::Initialize(
|
|||||||
m_height = height;
|
m_height = height;
|
||||||
m_format = format;
|
m_format = format;
|
||||||
|
|
||||||
|
result = device->CreatePixelShader(g_Pixel, sizeof(g_Pixel), NULL, &m_psCopy);
|
||||||
|
if (FAILED(result))
|
||||||
|
{
|
||||||
|
DeInitialize();
|
||||||
|
DEBUG_ERROR("Failed to create the copy pixel shader");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
case DXGI_FORMAT_NV12:
|
case FRAME_TYPE_YUV420:
|
||||||
result = device->CreatePixelShader(g_BGRAtoNV12, sizeof(g_BGRAtoNV12), NULL, &m_pixelShader);
|
result = device->CreatePixelShader(g_RGBtoYUV, sizeof(g_RGBtoYUV), NULL, &m_psConversion);
|
||||||
|
m_texFormats[0] = DXGI_FORMAT_R8_UNORM; m_scaleFormats[0] = 1.0f;
|
||||||
|
m_texFormats[1] = DXGI_FORMAT_R8_UNORM; m_scaleFormats[1] = 0.5f;
|
||||||
|
m_texFormats[2] = DXGI_FORMAT_R8_UNORM; m_scaleFormats[2] = 0.5f;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -93,7 +105,7 @@ bool TextureConverter::Initialize(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ZeroMemory(&texDesc , sizeof(texDesc ));
|
ZeroMemory(&texDesc , sizeof(texDesc ));
|
||||||
ZeroMemory(&viewDesc , sizeof(viewDesc ));
|
ZeroMemory(&targetDesc , sizeof(targetDesc ));
|
||||||
ZeroMemory(&shaderDesc , sizeof(shaderDesc ));
|
ZeroMemory(&shaderDesc , sizeof(shaderDesc ));
|
||||||
ZeroMemory(&samplerDesc, sizeof(samplerDesc));
|
ZeroMemory(&samplerDesc, sizeof(samplerDesc));
|
||||||
|
|
||||||
@ -105,9 +117,23 @@ bool TextureConverter::Initialize(
|
|||||||
texDesc.Usage = D3D11_USAGE_DEFAULT;
|
texDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||||
texDesc.CPUAccessFlags = 0;
|
texDesc.CPUAccessFlags = 0;
|
||||||
texDesc.MiscFlags = 0;
|
texDesc.MiscFlags = 0;
|
||||||
texDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
|
||||||
texDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
|
texDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
|
||||||
result = device->CreateTexture2D(&texDesc, NULL, &m_targetTexture);
|
|
||||||
|
targetDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||||
|
|
||||||
|
shaderDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||||
|
shaderDesc.Texture2D.MipLevels = 1;
|
||||||
|
|
||||||
|
for(int i = 0; i < _countof(m_targetTexture); ++i)
|
||||||
|
{
|
||||||
|
if (m_texFormats[i] == DXGI_FORMAT_UNKNOWN)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
texDesc .Format = m_texFormats[i];
|
||||||
|
targetDesc.Format = m_texFormats[i];
|
||||||
|
shaderDesc.Format = m_texFormats[i];
|
||||||
|
|
||||||
|
result = device->CreateTexture2D(&texDesc, NULL, &m_targetTexture[i]);
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
DeInitialize();
|
DeInitialize();
|
||||||
@ -115,10 +141,7 @@ bool TextureConverter::Initialize(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
viewDesc.Format = texDesc.Format;
|
result = device->CreateRenderTargetView(m_targetTexture[i], &targetDesc, &m_renderView[i]);
|
||||||
viewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
|
||||||
viewDesc.Texture2D.MipSlice = 0;
|
|
||||||
result = device->CreateRenderTargetView(m_targetTexture, &viewDesc, &m_renderView);
|
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
DeInitialize();
|
DeInitialize();
|
||||||
@ -126,6 +149,15 @@ bool TextureConverter::Initialize(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = device->CreateShaderResourceView(m_targetTexture[i], &shaderDesc, &m_shaderView[i]);
|
||||||
|
if (FAILED(result))
|
||||||
|
{
|
||||||
|
DeInitialize();
|
||||||
|
DEBUG_ERROR("Failed to create the resource view");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||||
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||||
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||||
@ -242,14 +274,21 @@ void TextureConverter::DeInitialize()
|
|||||||
SafeRelease(&m_samplerState );
|
SafeRelease(&m_samplerState );
|
||||||
SafeRelease(&m_indexBuffer );
|
SafeRelease(&m_indexBuffer );
|
||||||
SafeRelease(&m_vertexBuffer );
|
SafeRelease(&m_vertexBuffer );
|
||||||
SafeRelease(&m_renderView );
|
|
||||||
SafeRelease(&m_targetTexture);
|
for(int i = 0; i < _countof(m_targetTexture); ++i)
|
||||||
SafeRelease(&m_vertexShader );
|
{
|
||||||
SafeRelease(&m_pixelShader );
|
SafeRelease(&m_shaderView [i]);
|
||||||
SafeRelease(&m_layout );
|
SafeRelease(&m_renderView [i]);
|
||||||
|
SafeRelease(&m_targetTexture[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextureConverter::Convert(ID3D11Texture2DPtr &texture)
|
SafeRelease(&m_vertexShader);
|
||||||
|
SafeRelease(&m_psConversion);
|
||||||
|
SafeRelease(&m_layout );
|
||||||
|
SafeRelease(&m_psCopy );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextureConverter::Convert(ID3D11Texture2DPtr texture, TextureList & output)
|
||||||
{
|
{
|
||||||
unsigned int stride;
|
unsigned int stride;
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
@ -257,15 +296,15 @@ bool TextureConverter::Convert(ID3D11Texture2DPtr &texture)
|
|||||||
|
|
||||||
HRESULT result;
|
HRESULT result;
|
||||||
D3D11_TEXTURE2D_DESC texDesc;
|
D3D11_TEXTURE2D_DESC texDesc;
|
||||||
D3D11_SHADER_RESOURCE_VIEW_DESC shaderDesc;
|
D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
|
||||||
ID3D11ShaderResourceViewPtr textureView;
|
ID3D11ShaderResourceViewPtr textureView;
|
||||||
texture->GetDesc(&texDesc);
|
texture->GetDesc(&texDesc);
|
||||||
shaderDesc.Format = texDesc.Format;
|
viewDesc.Format = texDesc.Format;
|
||||||
shaderDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||||
shaderDesc.Texture2D.MostDetailedMip = 0;
|
viewDesc.Texture2D.MostDetailedMip = 0;
|
||||||
shaderDesc.Texture2D.MipLevels = 1;
|
viewDesc.Texture2D.MipLevels = 1;
|
||||||
|
|
||||||
result = m_device->CreateShaderResourceView(texture, &shaderDesc, &textureView);
|
result = m_device->CreateShaderResourceView(texture, &viewDesc, &textureView);
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
DeInitialize();
|
DeInitialize();
|
||||||
@ -273,9 +312,7 @@ bool TextureConverter::Convert(ID3D11Texture2DPtr &texture)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ID3D11Buffer *buffers [] = { m_vertexBuffer.GetInterfacePtr() };
|
ID3D11Buffer *buffers [] = { m_vertexBuffer.GetInterfacePtr() };
|
||||||
ID3D11RenderTargetView *renderViews [] = { m_renderView .GetInterfacePtr() };
|
|
||||||
ID3D11SamplerState *samplerStates[] = { m_samplerState.GetInterfacePtr() };
|
ID3D11SamplerState *samplerStates[] = { m_samplerState.GetInterfacePtr() };
|
||||||
ID3D11ShaderResourceView *shaderViews [] = { textureView .GetInterfacePtr() };
|
ID3D11ShaderResourceView *shaderViews [] = { textureView .GetInterfacePtr() };
|
||||||
D3D11_VIEWPORT viewPorts [] = { {
|
D3D11_VIEWPORT viewPorts [] = { {
|
||||||
@ -284,8 +321,21 @@ bool TextureConverter::Convert(ID3D11Texture2DPtr &texture)
|
|||||||
0.0f , 1.0f
|
0.0f , 1.0f
|
||||||
} };
|
} };
|
||||||
|
|
||||||
m_deviceContext->OMSetRenderTargets(1, renderViews, NULL);
|
int targetCount = 0;
|
||||||
m_deviceContext->ClearRenderTargetView(m_renderView, color);
|
ID3D11RenderTargetView **renderViews = new ID3D11RenderTargetView*[_countof(m_renderView)];
|
||||||
|
for(int i = 0; i < _countof(m_renderView); ++i)
|
||||||
|
{
|
||||||
|
if (m_texFormats[i] == DXGI_FORMAT_UNKNOWN)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
m_deviceContext->ClearRenderTargetView(m_renderView[i], color);
|
||||||
|
renderViews[i] = m_renderView[i].GetInterfacePtr();
|
||||||
|
++targetCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_deviceContext->PSSetShaderResources(0, _countof(shaderViews), shaderViews);
|
||||||
|
m_deviceContext->OMSetRenderTargets(targetCount, renderViews, NULL);
|
||||||
|
delete [] renderViews;
|
||||||
|
|
||||||
stride = sizeof(VS_INPUT);
|
stride = sizeof(VS_INPUT);
|
||||||
offset = 0;
|
offset = 0;
|
||||||
@ -296,14 +346,67 @@ bool TextureConverter::Convert(ID3D11Texture2DPtr &texture)
|
|||||||
m_deviceContext->IASetIndexBuffer (m_indexBuffer, DXGI_FORMAT_R32_UINT, 0);
|
m_deviceContext->IASetIndexBuffer (m_indexBuffer, DXGI_FORMAT_R32_UINT, 0);
|
||||||
m_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
m_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||||
m_deviceContext->VSSetShader (m_vertexShader, NULL, 0);
|
m_deviceContext->VSSetShader (m_vertexShader, NULL, 0);
|
||||||
|
|
||||||
m_deviceContext->PSSetSamplers (0, _countof(samplerStates), samplerStates);
|
m_deviceContext->PSSetSamplers (0, _countof(samplerStates), samplerStates);
|
||||||
m_deviceContext->PSSetShaderResources (0, _countof(shaderViews ), shaderViews );
|
m_deviceContext->PSSetShader (m_psConversion, NULL, 0);
|
||||||
m_deviceContext->PSSetShader (m_pixelShader , NULL, 0);
|
|
||||||
|
|
||||||
m_deviceContext->DrawIndexed(m_indexCount, 0, 0);
|
m_deviceContext->DrawIndexed(m_indexCount, 0, 0);
|
||||||
|
|
||||||
SafeRelease(&textureView);
|
SafeRelease(&textureView);
|
||||||
SafeRelease(&texture);
|
|
||||||
texture = m_targetTexture;
|
D3D11_RENDER_TARGET_VIEW_DESC targetDesc;
|
||||||
|
ZeroMemory(&targetDesc, sizeof(targetDesc));
|
||||||
|
targetDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||||
|
m_deviceContext->PSSetShader(m_psCopy, NULL, 0);
|
||||||
|
|
||||||
|
renderViews = new ID3D11RenderTargetView*[1];
|
||||||
|
for (int i = 0; i < _countof(m_renderView); ++i)
|
||||||
|
{
|
||||||
|
if (m_texFormats[i] == DXGI_FORMAT_UNKNOWN)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ID3D11Texture2DPtr src = m_targetTexture[i];
|
||||||
|
ID3D11Texture2DPtr dest;
|
||||||
|
ID3D11RenderTargetViewPtr view;
|
||||||
|
D3D11_TEXTURE2D_DESC srcDesc;
|
||||||
|
|
||||||
|
src->GetDesc(&srcDesc);
|
||||||
|
srcDesc.Width *= m_scaleFormats[i];
|
||||||
|
srcDesc.Height *= m_scaleFormats[i];
|
||||||
|
viewPorts[0].Width = srcDesc.Width;
|
||||||
|
viewPorts[0].Height = srcDesc.Height;
|
||||||
|
|
||||||
|
result = m_device->CreateTexture2D(&srcDesc, NULL, &dest);
|
||||||
|
if (FAILED(result))
|
||||||
|
{
|
||||||
|
delete[] renderViews;
|
||||||
|
DeInitialize();
|
||||||
|
DEBUG_ERROR("Failed to create the target texture");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
targetDesc.Format = srcDesc.Format;
|
||||||
|
result = m_device->CreateRenderTargetView(dest, &targetDesc, &view);
|
||||||
|
if (FAILED(result))
|
||||||
|
{
|
||||||
|
SafeRelease(&dest);
|
||||||
|
delete[] renderViews;
|
||||||
|
DeInitialize();
|
||||||
|
DEBUG_ERROR("Failed to create the target view");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderViews[0] = view.GetInterfacePtr();
|
||||||
|
shaderViews[0] = m_shaderView[i].GetInterfacePtr();
|
||||||
|
|
||||||
|
m_deviceContext->OMSetRenderTargets(1, renderViews, NULL);
|
||||||
|
m_deviceContext->RSSetViewports(_countof(viewPorts), viewPorts);
|
||||||
|
m_deviceContext->PSSetShaderResources(0, 1, shaderViews);
|
||||||
|
m_deviceContext->DrawIndexed(m_indexCount, 0, 0);
|
||||||
|
|
||||||
|
output.push_back(dest);
|
||||||
|
SafeRelease(&view);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] renderViews;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,12 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Com.h"
|
#include "Com.h"
|
||||||
|
#include "common\KVMFR.h"
|
||||||
|
|
||||||
#include <DirectXMath.h>
|
#include <DirectXMath.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
typedef std::vector<ID3D11Texture2DPtr> TextureList;
|
||||||
|
|
||||||
class TextureConverter
|
class TextureConverter
|
||||||
{
|
{
|
||||||
@ -34,12 +38,12 @@ public:
|
|||||||
ID3D11DevicePtr device,
|
ID3D11DevicePtr device,
|
||||||
const unsigned int width,
|
const unsigned int width,
|
||||||
const unsigned int height,
|
const unsigned int height,
|
||||||
DXGI_FORMAT format
|
FrameType format
|
||||||
);
|
);
|
||||||
|
|
||||||
void DeInitialize();
|
void DeInitialize();
|
||||||
|
|
||||||
bool Convert(ID3D11Texture2DPtr &texture);
|
bool Convert(ID3D11Texture2DPtr texture, TextureList & output);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct VS_INPUT
|
struct VS_INPUT
|
||||||
@ -53,13 +57,19 @@ private:
|
|||||||
ID3D11DeviceContextPtr m_deviceContext;
|
ID3D11DeviceContextPtr m_deviceContext;
|
||||||
ID3D11DevicePtr m_device;
|
ID3D11DevicePtr m_device;
|
||||||
unsigned int m_width, m_height;
|
unsigned int m_width, m_height;
|
||||||
DXGI_FORMAT m_format;
|
FrameType m_format;
|
||||||
|
|
||||||
|
DXGI_FORMAT m_texFormats [3];
|
||||||
|
float m_scaleFormats [3];
|
||||||
|
|
||||||
|
ID3D11Texture2DPtr m_targetTexture[3];
|
||||||
|
ID3D11RenderTargetViewPtr m_renderView [3];
|
||||||
|
ID3D11ShaderResourceViewPtr m_shaderView [3];
|
||||||
|
|
||||||
ID3D11Texture2DPtr m_targetTexture;
|
|
||||||
ID3D11RenderTargetViewPtr m_renderView;
|
|
||||||
ID3D11InputLayoutPtr m_layout;
|
ID3D11InputLayoutPtr m_layout;
|
||||||
ID3D11VertexShaderPtr m_vertexShader;
|
ID3D11VertexShaderPtr m_vertexShader;
|
||||||
ID3D11PixelShaderPtr m_pixelShader;
|
ID3D11PixelShaderPtr m_psCopy;
|
||||||
|
ID3D11PixelShaderPtr m_psConversion;
|
||||||
ID3D11SamplerStatePtr m_samplerState;
|
ID3D11SamplerStatePtr m_samplerState;
|
||||||
|
|
||||||
ID3D11BufferPtr m_vertexBuffer;
|
ID3D11BufferPtr m_vertexBuffer;
|
||||||
|
@ -359,11 +359,16 @@
|
|||||||
<MASM Include="..\common\memcpySSE.asm" />
|
<MASM Include="..\common\memcpySSE.asm" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<FxCompile Include="Shaders\BGRAtoNV12.hlsl">
|
<FxCompile Include="Shaders\Pixel.hlsl">
|
||||||
|
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Pixel</ShaderType>
|
||||||
|
<VariableName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">g_Pixel</VariableName>
|
||||||
|
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Shaders\Pixel.h</HeaderFileOutput>
|
||||||
|
</FxCompile>
|
||||||
|
<FxCompile Include="Shaders\RGBtoYUV.hlsl">
|
||||||
<FileType>HLSL</FileType>
|
<FileType>HLSL</FileType>
|
||||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Pixel</ShaderType>
|
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Pixel</ShaderType>
|
||||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">g_BGRAtoNV12</VariableName>
|
<VariableName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">g_RGBtoYUV</VariableName>
|
||||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Shaders\BGRAtoNV12.h</HeaderFileOutput>
|
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Shaders\RGBtoYUV.h</HeaderFileOutput>
|
||||||
</FxCompile>
|
</FxCompile>
|
||||||
<FxCompile Include="Shaders\Vertex.hlsl">
|
<FxCompile Include="Shaders\Vertex.hlsl">
|
||||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Vertex</ShaderType>
|
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Vertex</ShaderType>
|
||||||
|
@ -105,11 +105,12 @@
|
|||||||
</MASM>
|
</MASM>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<FxCompile Include="Shaders\BGRAtoNV12.hlsl">
|
|
||||||
<Filter>Source Files\Shaders</Filter>
|
|
||||||
</FxCompile>
|
|
||||||
<FxCompile Include="Shaders\Vertex.hlsl">
|
<FxCompile Include="Shaders\Vertex.hlsl">
|
||||||
<Filter>Source Files\Shaders</Filter>
|
<Filter>Source Files\Shaders</Filter>
|
||||||
</FxCompile>
|
</FxCompile>
|
||||||
|
<FxCompile Include="Shaders\RGBtoYUV.hlsl">
|
||||||
|
<Filter>Source Files\Shaders</Filter>
|
||||||
|
</FxCompile>
|
||||||
|
<FxCompile Include="Shaders\Pixel.hlsl" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
Loading…
Reference in New Issue
Block a user