New upstream version 23.2.1+dfsg1
This commit is contained in:
parent
cdc9a9fc87
commit
b14f9eae6d
1017 changed files with 37232 additions and 11111 deletions
|
|
@ -30,6 +30,7 @@ set_target_properties(libobs-d3d11
|
|||
PREFIX "")
|
||||
target_link_libraries(libobs-d3d11
|
||||
libobs
|
||||
d3d9
|
||||
d3d11
|
||||
dxgi)
|
||||
|
||||
|
|
|
|||
|
|
@ -17,14 +17,14 @@
|
|||
|
||||
#include "d3d11-subsystem.hpp"
|
||||
|
||||
inline void gs_vertex_buffer::Rebuild()
|
||||
void gs_vertex_buffer::Rebuild()
|
||||
{
|
||||
uvBuffers.clear();
|
||||
uvSizes.clear();
|
||||
BuildBuffers();
|
||||
}
|
||||
|
||||
inline void gs_index_buffer::Rebuild(ID3D11Device *dev)
|
||||
void gs_index_buffer::Rebuild(ID3D11Device *dev)
|
||||
{
|
||||
HRESULT hr = dev->CreateBuffer(&bd, &srd, &indexBuffer);
|
||||
if (FAILED(hr))
|
||||
|
|
@ -55,7 +55,7 @@ void gs_texture_2d::RebuildSharedTextureFallback()
|
|||
isShared = false;
|
||||
}
|
||||
|
||||
inline void gs_texture_2d::Rebuild(ID3D11Device *dev)
|
||||
void gs_texture_2d::Rebuild(ID3D11Device *dev)
|
||||
{
|
||||
HRESULT hr;
|
||||
if (isShared) {
|
||||
|
|
@ -89,9 +89,61 @@ inline void gs_texture_2d::Rebuild(ID3D11Device *dev)
|
|||
if (FAILED(hr))
|
||||
throw HRError("Failed to create GDI surface", hr);
|
||||
}
|
||||
|
||||
acquired = false;
|
||||
|
||||
if ((td.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0) {
|
||||
ComQIPtr<IDXGIResource> dxgi_res(texture);
|
||||
if (dxgi_res)
|
||||
GetSharedHandle(dxgi_res);
|
||||
device_texture_acquire_sync(this, 0, INFINITE);
|
||||
}
|
||||
}
|
||||
|
||||
inline void gs_zstencil_buffer::Rebuild(ID3D11Device *dev)
|
||||
void gs_texture_2d::RebuildNV12_Y(ID3D11Device *dev)
|
||||
{
|
||||
gs_texture_2d *tex_uv = pairedNV12texture;
|
||||
HRESULT hr;
|
||||
|
||||
hr = dev->CreateTexture2D(&td, nullptr, &texture);
|
||||
if (FAILED(hr))
|
||||
throw HRError("Failed to create 2D texture", hr);
|
||||
|
||||
hr = dev->CreateShaderResourceView(texture, &resourceDesc, &shaderRes);
|
||||
if (FAILED(hr))
|
||||
throw HRError("Failed to create resource view", hr);
|
||||
|
||||
if (isRenderTarget)
|
||||
InitRenderTargets();
|
||||
|
||||
tex_uv->RebuildNV12_UV(dev);
|
||||
|
||||
acquired = false;
|
||||
|
||||
if ((td.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0) {
|
||||
ComQIPtr<IDXGIResource> dxgi_res(texture);
|
||||
if (dxgi_res)
|
||||
GetSharedHandle(dxgi_res);
|
||||
device_texture_acquire_sync(this, 0, INFINITE);
|
||||
}
|
||||
}
|
||||
|
||||
void gs_texture_2d::RebuildNV12_UV(ID3D11Device *dev)
|
||||
{
|
||||
gs_texture_2d *tex_y = pairedNV12texture;
|
||||
HRESULT hr;
|
||||
|
||||
texture = tex_y->texture;
|
||||
|
||||
hr = dev->CreateShaderResourceView(texture, &resourceDesc, &shaderRes);
|
||||
if (FAILED(hr))
|
||||
throw HRError("Failed to create resource view", hr);
|
||||
|
||||
if (isRenderTarget)
|
||||
InitRenderTargets();
|
||||
}
|
||||
|
||||
void gs_zstencil_buffer::Rebuild(ID3D11Device *dev)
|
||||
{
|
||||
HRESULT hr;
|
||||
hr = dev->CreateTexture2D(&td, nullptr, &texture);
|
||||
|
|
@ -103,21 +155,21 @@ inline void gs_zstencil_buffer::Rebuild(ID3D11Device *dev)
|
|||
throw HRError("Failed to create depth stencil view", hr);
|
||||
}
|
||||
|
||||
inline void gs_stage_surface::Rebuild(ID3D11Device *dev)
|
||||
void gs_stage_surface::Rebuild(ID3D11Device *dev)
|
||||
{
|
||||
HRESULT hr = dev->CreateTexture2D(&td, nullptr, &texture);
|
||||
if (FAILED(hr))
|
||||
throw HRError("Failed to create staging surface", hr);
|
||||
}
|
||||
|
||||
inline void gs_sampler_state::Rebuild(ID3D11Device *dev)
|
||||
void gs_sampler_state::Rebuild(ID3D11Device *dev)
|
||||
{
|
||||
HRESULT hr = dev->CreateSamplerState(&sd, state.Assign());
|
||||
if (FAILED(hr))
|
||||
throw HRError("Failed to create sampler state", hr);
|
||||
}
|
||||
|
||||
inline void gs_vertex_shader::Rebuild(ID3D11Device *dev)
|
||||
void gs_vertex_shader::Rebuild(ID3D11Device *dev)
|
||||
{
|
||||
HRESULT hr;
|
||||
hr = dev->CreateVertexShader(data.data(), data.size(), nullptr, &shader);
|
||||
|
|
@ -142,7 +194,7 @@ inline void gs_vertex_shader::Rebuild(ID3D11Device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
inline void gs_pixel_shader::Rebuild(ID3D11Device *dev)
|
||||
void gs_pixel_shader::Rebuild(ID3D11Device *dev)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
|
|
@ -164,7 +216,7 @@ inline void gs_pixel_shader::Rebuild(ID3D11Device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
inline void gs_swap_chain::Rebuild(ID3D11Device *dev)
|
||||
void gs_swap_chain::Rebuild(ID3D11Device *dev)
|
||||
{
|
||||
HRESULT hr = device->factory->CreateSwapChain(dev, &swapDesc, &swap);
|
||||
if (FAILED(hr))
|
||||
|
|
@ -172,21 +224,21 @@ inline void gs_swap_chain::Rebuild(ID3D11Device *dev)
|
|||
Init();
|
||||
}
|
||||
|
||||
inline void SavedBlendState::Rebuild(ID3D11Device *dev)
|
||||
void SavedBlendState::Rebuild(ID3D11Device *dev)
|
||||
{
|
||||
HRESULT hr = dev->CreateBlendState(&bd, &state);
|
||||
if (FAILED(hr))
|
||||
throw HRError("Failed to create blend state", hr);
|
||||
}
|
||||
|
||||
inline void SavedZStencilState::Rebuild(ID3D11Device *dev)
|
||||
void SavedZStencilState::Rebuild(ID3D11Device *dev)
|
||||
{
|
||||
HRESULT hr = dev->CreateDepthStencilState(&dsd, &state);
|
||||
if (FAILED(hr))
|
||||
throw HRError("Failed to create depth stencil state", hr);
|
||||
}
|
||||
|
||||
inline void SavedRasterState::Rebuild(ID3D11Device *dev)
|
||||
void SavedRasterState::Rebuild(ID3D11Device *dev)
|
||||
{
|
||||
HRESULT hr = dev->CreateRasterizerState(&rd, &state);
|
||||
if (FAILED(hr))
|
||||
|
|
@ -287,7 +339,14 @@ try {
|
|||
((gs_index_buffer*)obj)->Rebuild(dev);
|
||||
break;
|
||||
case gs_type::gs_texture_2d:
|
||||
((gs_texture_2d*)obj)->Rebuild(dev);
|
||||
{
|
||||
gs_texture_2d *tex = (gs_texture_2d*)obj;
|
||||
if (!tex->nv12) {
|
||||
tex->Rebuild(dev);
|
||||
} else if (!tex->chroma) {
|
||||
tex->RebuildNV12_Y(dev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case gs_type::gs_zstencil_buffer:
|
||||
((gs_zstencil_buffer*)obj)->Rebuild(dev);
|
||||
|
|
|
|||
|
|
@ -137,8 +137,11 @@ void gs_shader::BuildConstantBuffer()
|
|||
case GS_SHADER_PARAM_BOOL:
|
||||
case GS_SHADER_PARAM_INT:
|
||||
case GS_SHADER_PARAM_FLOAT: size = sizeof(float); break;
|
||||
case GS_SHADER_PARAM_INT2:
|
||||
case GS_SHADER_PARAM_VEC2: size = sizeof(vec2); break;
|
||||
case GS_SHADER_PARAM_INT3:
|
||||
case GS_SHADER_PARAM_VEC3: size = sizeof(float)*3; break;
|
||||
case GS_SHADER_PARAM_INT4:
|
||||
case GS_SHADER_PARAM_VEC4: size = sizeof(vec4); break;
|
||||
case GS_SHADER_PARAM_MATRIX4X4:
|
||||
size = sizeof(float)*4*4;
|
||||
|
|
|
|||
|
|
@ -41,3 +41,28 @@ gs_stage_surface::gs_stage_surface(gs_device_t *device, uint32_t width,
|
|||
if (FAILED(hr))
|
||||
throw HRError("Failed to create staging surface", hr);
|
||||
}
|
||||
|
||||
gs_stage_surface::gs_stage_surface(gs_device_t *device, uint32_t width,
|
||||
uint32_t height)
|
||||
: gs_obj (device, gs_type::gs_stage_surface),
|
||||
width (width),
|
||||
height (height),
|
||||
format (GS_UNKNOWN),
|
||||
dxgiFormat (DXGI_FORMAT_NV12)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
memset(&td, 0, sizeof(td));
|
||||
td.Width = width;
|
||||
td.Height = height;
|
||||
td.MipLevels = 1;
|
||||
td.ArraySize = 1;
|
||||
td.Format = dxgiFormat;
|
||||
td.SampleDesc.Count = 1;
|
||||
td.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
td.Usage = D3D11_USAGE_STAGING;
|
||||
|
||||
hr = device->device->CreateTexture2D(&td, NULL, texture.Assign());
|
||||
if (FAILED(hr))
|
||||
throw HRError("Failed to create staging surface", hr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,10 @@
|
|||
#include <cinttypes>
|
||||
#include <util/base.h>
|
||||
#include <util/platform.h>
|
||||
#include <util/dstr.h>
|
||||
#include <util/util.hpp>
|
||||
#include <graphics/matrix3.h>
|
||||
#include <d3d9.h>
|
||||
#include "d3d11-subsystem.hpp"
|
||||
|
||||
struct UnsupportedHWError : HRError {
|
||||
|
|
@ -227,6 +230,120 @@ const static D3D_FEATURE_LEVEL featureLevels[] =
|
|||
D3D_FEATURE_LEVEL_9_3,
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define VERT_IN_OUT "\
|
||||
struct VertInOut { \
|
||||
float4 pos : POSITION; \
|
||||
}; "
|
||||
|
||||
#define NV12_Y_PS VERT_IN_OUT "\
|
||||
float main(VertInOut vert_in) : TARGET \
|
||||
{ \
|
||||
return 1.0; \
|
||||
}"
|
||||
|
||||
#define NV12_UV_PS VERT_IN_OUT "\
|
||||
float2 main(VertInOut vert_in) : TARGET \
|
||||
{ \
|
||||
return float2(1.0, 1.0); \
|
||||
}"
|
||||
|
||||
#define NV12_VS VERT_IN_OUT "\
|
||||
VertInOut main(VertInOut vert_in) \
|
||||
{ \
|
||||
VertInOut vert_out; \
|
||||
vert_out.pos = float4(vert_in.pos.xyz, 1.0); \
|
||||
return vert_out; \
|
||||
} "
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define NV12_CX 128
|
||||
#define NV12_CY 128
|
||||
|
||||
bool gs_device::HasBadNV12Output()
|
||||
try {
|
||||
vec3 points[4];
|
||||
vec3_set(&points[0], -1.0f, -1.0f, 0.0f);
|
||||
vec3_set(&points[1], -1.0f, 1.0f, 0.0f);
|
||||
vec3_set(&points[2], 1.0f, -1.0f, 0.0f);
|
||||
vec3_set(&points[3], 1.0f, 1.0f, 0.0f);
|
||||
|
||||
gs_texture_2d nv12_y(this, NV12_CX, NV12_CY, GS_R8, 1, nullptr,
|
||||
GS_RENDER_TARGET | GS_SHARED_KM_TEX, GS_TEXTURE_2D,
|
||||
false, true);
|
||||
gs_texture_2d nv12_uv(this, nv12_y.texture,
|
||||
GS_RENDER_TARGET | GS_SHARED_KM_TEX);
|
||||
gs_vertex_shader nv12_vs(this, "", NV12_VS);
|
||||
gs_pixel_shader nv12_y_ps(this, "", NV12_Y_PS);
|
||||
gs_pixel_shader nv12_uv_ps(this, "", NV12_UV_PS);
|
||||
gs_stage_surface nv12_stage(this, NV12_CX, NV12_CY);
|
||||
|
||||
gs_vb_data *vbd = gs_vbdata_create();
|
||||
vbd->num = 4;
|
||||
vbd->points = (vec3*)bmemdup(&points, sizeof(points));
|
||||
|
||||
gs_vertex_buffer buf(this, vbd, 0);
|
||||
|
||||
device_load_vertexbuffer(this, &buf);
|
||||
device_load_vertexshader(this, &nv12_vs);
|
||||
|
||||
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
|
||||
device_set_viewport(this, 0, 0, NV12_CX, NV12_CY);
|
||||
device_set_cull_mode(this, GS_NEITHER);
|
||||
device_enable_depth_test(this, false);
|
||||
device_enable_blending(this, false);
|
||||
LoadVertexBufferData();
|
||||
|
||||
device_set_render_target(this, &nv12_y, nullptr);
|
||||
device_load_pixelshader(this, &nv12_y_ps);
|
||||
UpdateBlendState();
|
||||
UpdateRasterState();
|
||||
UpdateZStencilState();
|
||||
context->Draw(4, 0);
|
||||
|
||||
device_set_viewport(this, 0, 0, NV12_CX/2, NV12_CY/2);
|
||||
device_set_render_target(this, &nv12_uv, nullptr);
|
||||
device_load_pixelshader(this, &nv12_uv_ps);
|
||||
UpdateBlendState();
|
||||
UpdateRasterState();
|
||||
UpdateZStencilState();
|
||||
context->Draw(4, 0);
|
||||
|
||||
device_load_pixelshader(this, nullptr);
|
||||
device_load_vertexshader(this, nullptr);
|
||||
device_set_render_target(this, nullptr, nullptr);
|
||||
|
||||
device_stage_texture(this, &nv12_stage, &nv12_y);
|
||||
|
||||
uint8_t *data;
|
||||
uint32_t linesize;
|
||||
bool bad_driver = false;
|
||||
|
||||
if (gs_stagesurface_map(&nv12_stage, &data, &linesize)) {
|
||||
bad_driver = data[linesize * NV12_CY] == 0;
|
||||
gs_stagesurface_unmap(&nv12_stage);
|
||||
} else {
|
||||
throw "Could not map surface";
|
||||
}
|
||||
|
||||
if (bad_driver) {
|
||||
blog(LOG_WARNING, "Bad NV12 texture handling detected! "
|
||||
"Disabling NV12 texture support.");
|
||||
}
|
||||
return bad_driver;
|
||||
|
||||
} catch (HRError error) {
|
||||
blog(LOG_WARNING, "HasBadNV12Output failed: %s (%08lX)",
|
||||
error.str, error.hr);
|
||||
return false;
|
||||
} catch (const char *error) {
|
||||
blog(LOG_WARNING, "HasBadNV12Output failed: %s", error);
|
||||
return false;
|
||||
}
|
||||
|
||||
void gs_device::InitDevice(uint32_t adapterIdx)
|
||||
{
|
||||
wstring adapterName;
|
||||
|
|
@ -244,11 +361,10 @@ void gs_device::InitDevice(uint32_t adapterIdx)
|
|||
adapterName = (adapter->GetDesc(&desc) == S_OK) ? desc.Description :
|
||||
L"<unknown>";
|
||||
|
||||
char *adapterNameUTF8;
|
||||
BPtr<char> adapterNameUTF8;
|
||||
os_wcs_to_utf8_ptr(adapterName.c_str(), 0, &adapterNameUTF8);
|
||||
blog(LOG_INFO, "Loading up D3D11 on adapter %s (%" PRIu32 ")",
|
||||
adapterNameUTF8, adapterIdx);
|
||||
bfree(adapterNameUTF8);
|
||||
adapterNameUTF8.Get(), adapterIdx);
|
||||
|
||||
hr = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN,
|
||||
NULL, createFlags, featureLevels,
|
||||
|
|
@ -260,6 +376,49 @@ void gs_device::InitDevice(uint32_t adapterIdx)
|
|||
|
||||
blog(LOG_INFO, "D3D11 loaded successfully, feature level used: %u",
|
||||
(unsigned int)levelUsed);
|
||||
|
||||
/* ---------------------------------------- */
|
||||
/* check for nv12 texture output support */
|
||||
|
||||
nv12Supported = false;
|
||||
|
||||
ComQIPtr<ID3D11Device1> d3d11_1(device);
|
||||
if (!d3d11_1) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* needs to support extended resource sharing */
|
||||
D3D11_FEATURE_DATA_D3D11_OPTIONS opts = {};
|
||||
hr = d3d11_1->CheckFeatureSupport(
|
||||
D3D11_FEATURE_D3D11_OPTIONS,
|
||||
&opts, sizeof(opts));
|
||||
if (FAILED(hr) || !opts.ExtendedResourceSharing) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* needs to support the actual format */
|
||||
UINT support = 0;
|
||||
hr = device->CheckFormatSupport(
|
||||
DXGI_FORMAT_NV12,
|
||||
&support);
|
||||
if (FAILED(hr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((support & D3D11_FORMAT_SUPPORT_TEXTURE2D) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* must be usable as a render target */
|
||||
if ((support & D3D11_FORMAT_SUPPORT_RENDER_TARGET) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasBadNV12Output()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nv12Supported = true;
|
||||
}
|
||||
|
||||
static inline void ConvertStencilSide(D3D11_DEPTH_STENCILOP_DESC &desc,
|
||||
|
|
@ -505,7 +664,7 @@ static inline void EnumD3DAdapters(
|
|||
ComPtr<IDXGIFactory1> factory;
|
||||
ComPtr<IDXGIAdapter1> adapter;
|
||||
HRESULT hr;
|
||||
UINT i = 0;
|
||||
UINT i;
|
||||
|
||||
IID factoryIID = (GetWinVer() >= 0x602) ? dxgiFactory2 :
|
||||
__uuidof(IDXGIFactory1);
|
||||
|
|
@ -514,7 +673,7 @@ static inline void EnumD3DAdapters(
|
|||
if (FAILED(hr))
|
||||
throw HRError("Failed to create DXGIFactory", hr);
|
||||
|
||||
while (factory->EnumAdapters1(i++, adapter.Assign()) == S_OK) {
|
||||
for (i = 0; factory->EnumAdapters1(i, adapter.Assign()) == S_OK; ++i) {
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
char name[512] = "";
|
||||
|
||||
|
|
@ -528,7 +687,7 @@ static inline void EnumD3DAdapters(
|
|||
|
||||
os_wcs_to_utf8(desc.Description, 0, name, sizeof(name));
|
||||
|
||||
if (!callback(param, name, i - 1))
|
||||
if (!callback(param, name, i))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -550,10 +709,10 @@ bool device_enum_adapters(
|
|||
|
||||
static inline void LogAdapterMonitors(IDXGIAdapter1 *adapter)
|
||||
{
|
||||
UINT i = 0;
|
||||
UINT i;
|
||||
ComPtr<IDXGIOutput> output;
|
||||
|
||||
while (adapter->EnumOutputs(i++, &output) == S_OK) {
|
||||
for (i = 0; adapter->EnumOutputs(i, &output) == S_OK; ++i) {
|
||||
DXGI_OUTPUT_DESC desc;
|
||||
if (FAILED(output->GetDesc(&desc)))
|
||||
continue;
|
||||
|
|
@ -575,7 +734,7 @@ static inline void LogD3DAdapters()
|
|||
ComPtr<IDXGIFactory1> factory;
|
||||
ComPtr<IDXGIAdapter1> adapter;
|
||||
HRESULT hr;
|
||||
UINT i = 0;
|
||||
UINT i;
|
||||
|
||||
blog(LOG_INFO, "Available Video Adapters: ");
|
||||
|
||||
|
|
@ -586,7 +745,7 @@ static inline void LogD3DAdapters()
|
|||
if (FAILED(hr))
|
||||
throw HRError("Failed to create DXGIFactory", hr);
|
||||
|
||||
while (factory->EnumAdapters1(i++, adapter.Assign()) == S_OK) {
|
||||
for (i = 0; factory->EnumAdapters1(i, adapter.Assign()) == S_OK; ++i) {
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
char name[512] = "";
|
||||
|
||||
|
|
@ -736,8 +895,7 @@ gs_texture_t *device_texture_create(gs_device_t *device, uint32_t width,
|
|||
gs_texture *texture = NULL;
|
||||
try {
|
||||
texture = new gs_texture_2d(device, width, height, color_format,
|
||||
levels, data, flags, GS_TEXTURE_2D, false,
|
||||
false);
|
||||
levels, data, flags, GS_TEXTURE_2D, false);
|
||||
} catch (HRError error) {
|
||||
blog(LOG_ERROR, "device_texture_create (D3D11): %s (%08lX)",
|
||||
error.str, error.hr);
|
||||
|
|
@ -756,8 +914,7 @@ gs_texture_t *device_cubetexture_create(gs_device_t *device, uint32_t size,
|
|||
gs_texture *texture = NULL;
|
||||
try {
|
||||
texture = new gs_texture_2d(device, size, size, color_format,
|
||||
levels, data, flags, GS_TEXTURE_CUBE, false,
|
||||
false);
|
||||
levels, data, flags, GS_TEXTURE_CUBE, false);
|
||||
} catch (HRError error) {
|
||||
blog(LOG_ERROR, "device_cubetexture_create (D3D11): %s "
|
||||
"(%08lX)",
|
||||
|
|
@ -1317,7 +1474,7 @@ void device_stage_texture(gs_device_t *device, gs_stagesurf_t *dst,
|
|||
throw "Source texture must be a 2D texture";
|
||||
if (!dst)
|
||||
throw "Destination surface is NULL";
|
||||
if (dst->format != src->format)
|
||||
if (dst->format != GS_UNKNOWN && dst->format != src->format)
|
||||
throw "Source and destination formats do not match";
|
||||
if (dst->width != src2d->width ||
|
||||
dst->height != src2d->height)
|
||||
|
|
@ -2056,6 +2213,29 @@ extern "C" EXPORT bool device_shared_texture_available(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
extern "C" EXPORT bool device_nv12_available(gs_device_t *device)
|
||||
{
|
||||
return device->nv12Supported;
|
||||
}
|
||||
|
||||
extern "C" EXPORT void device_debug_marker_begin(gs_device_t *,
|
||||
const char *markername, const float color[4])
|
||||
{
|
||||
D3DCOLOR bgra = D3DCOLOR_ARGB((DWORD)(255.0f * color[3]),
|
||||
(DWORD)(255.0f * color[0]), (DWORD)(255.0f * color[1]),
|
||||
(DWORD)(255.0f * color[2]));
|
||||
|
||||
wchar_t wide[64];
|
||||
os_utf8_to_wcs(markername, 0, wide, _countof(wide));
|
||||
|
||||
D3DPERF_BeginEvent(bgra, wide);
|
||||
}
|
||||
|
||||
extern "C" EXPORT void device_debug_marker_end(gs_device_t *)
|
||||
{
|
||||
D3DPERF_EndEvent();
|
||||
}
|
||||
|
||||
extern "C" EXPORT gs_texture_t *device_texture_create_gdi(gs_device_t *device,
|
||||
uint32_t width, uint32_t height)
|
||||
{
|
||||
|
|
@ -2063,7 +2243,7 @@ extern "C" EXPORT gs_texture_t *device_texture_create_gdi(gs_device_t *device,
|
|||
try {
|
||||
texture = new gs_texture_2d(device, width, height, GS_BGRA,
|
||||
1, nullptr, GS_RENDER_TARGET, GS_TEXTURE_2D,
|
||||
true, false);
|
||||
true);
|
||||
} catch (HRError error) {
|
||||
blog(LOG_ERROR, "device_texture_create_gdi (D3D11): %s (%08lX)",
|
||||
error.str, error.hr);
|
||||
|
|
@ -2132,3 +2312,112 @@ extern "C" EXPORT gs_texture_t *device_texture_open_shared(gs_device_t *device,
|
|||
|
||||
return texture;
|
||||
}
|
||||
|
||||
extern "C" EXPORT uint32_t device_texture_get_shared_handle(gs_texture_t *tex)
|
||||
{
|
||||
gs_texture_2d *tex2d = reinterpret_cast<gs_texture_2d *>(tex);
|
||||
if (tex->type != GS_TEXTURE_2D)
|
||||
return GS_INVALID_HANDLE;
|
||||
|
||||
return tex2d->isShared ? tex2d->sharedHandle : GS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
int device_texture_acquire_sync(gs_texture_t *tex, uint64_t key, uint32_t ms)
|
||||
{
|
||||
gs_texture_2d *tex2d = reinterpret_cast<gs_texture_2d *>(tex);
|
||||
if (tex->type != GS_TEXTURE_2D)
|
||||
return -1;
|
||||
|
||||
if (tex2d->acquired)
|
||||
return 0;
|
||||
|
||||
ComQIPtr<IDXGIKeyedMutex> keyedMutex(tex2d->texture);
|
||||
if (!keyedMutex)
|
||||
return -1;
|
||||
|
||||
HRESULT hr = keyedMutex->AcquireSync(key, ms);
|
||||
if (hr == S_OK) {
|
||||
tex2d->acquired = true;
|
||||
return 0;
|
||||
} else if (hr == WAIT_TIMEOUT) {
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" EXPORT int device_texture_release_sync(gs_texture_t *tex,
|
||||
uint64_t key)
|
||||
{
|
||||
gs_texture_2d *tex2d = reinterpret_cast<gs_texture_2d *>(tex);
|
||||
if (tex->type != GS_TEXTURE_2D)
|
||||
return -1;
|
||||
|
||||
if (!tex2d->acquired)
|
||||
return 0;
|
||||
|
||||
ComQIPtr<IDXGIKeyedMutex> keyedMutex(tex2d->texture);
|
||||
if (!keyedMutex)
|
||||
return -1;
|
||||
|
||||
HRESULT hr = keyedMutex->ReleaseSync(key);
|
||||
if (hr == S_OK) {
|
||||
tex2d->acquired = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" EXPORT bool device_texture_create_nv12(gs_device_t *device,
|
||||
gs_texture_t **p_tex_y, gs_texture_t **p_tex_uv,
|
||||
uint32_t width, uint32_t height, uint32_t flags)
|
||||
{
|
||||
if (!device->nv12Supported)
|
||||
return false;
|
||||
|
||||
*p_tex_y = nullptr;
|
||||
*p_tex_uv = nullptr;
|
||||
|
||||
gs_texture_2d *tex_y;
|
||||
gs_texture_2d *tex_uv;
|
||||
|
||||
try {
|
||||
tex_y = new gs_texture_2d(device, width, height, GS_R8, 1,
|
||||
nullptr, flags, GS_TEXTURE_2D, false, true);
|
||||
tex_uv = new gs_texture_2d(device, tex_y->texture, flags);
|
||||
|
||||
} catch (HRError error) {
|
||||
blog(LOG_ERROR, "gs_texture_create_nv12 (D3D11): %s (%08lX)",
|
||||
error.str, error.hr);
|
||||
LogD3D11ErrorDetails(error, device);
|
||||
return false;
|
||||
|
||||
} catch (const char *error) {
|
||||
blog(LOG_ERROR, "gs_texture_create_nv12 (D3D11): %s", error);
|
||||
return false;
|
||||
}
|
||||
|
||||
tex_y->pairedNV12texture = tex_uv;
|
||||
tex_uv->pairedNV12texture = tex_y;
|
||||
|
||||
*p_tex_y = tex_y;
|
||||
*p_tex_uv = tex_uv;
|
||||
return true;
|
||||
}
|
||||
|
||||
extern "C" EXPORT gs_stagesurf_t *device_stagesurface_create_nv12(
|
||||
gs_device_t *device, uint32_t width, uint32_t height)
|
||||
{
|
||||
gs_stage_surface *surf = NULL;
|
||||
try {
|
||||
surf = new gs_stage_surface(device, width, height);
|
||||
} catch (HRError error) {
|
||||
blog(LOG_ERROR, "device_stagesurface_create (D3D11): %s "
|
||||
"(%08lX)",
|
||||
error.str, error.hr);
|
||||
LogD3D11ErrorDetails(error, device);
|
||||
}
|
||||
|
||||
return surf;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#include <windows.h>
|
||||
#include <dxgi.h>
|
||||
#include <dxgi1_2.h>
|
||||
#include <d3d11.h>
|
||||
#include <d3d11_1.h>
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
#include <util/base.h>
|
||||
|
|
@ -80,6 +80,7 @@ static inline DXGI_FORMAT ConvertGSTextureFormat(gs_color_format format)
|
|||
case GS_DXT1: return DXGI_FORMAT_BC1_UNORM;
|
||||
case GS_DXT3: return DXGI_FORMAT_BC2_UNORM;
|
||||
case GS_DXT5: return DXGI_FORMAT_BC3_UNORM;
|
||||
case GS_R8G8: return DXGI_FORMAT_R8G8_UNORM;
|
||||
}
|
||||
|
||||
return DXGI_FORMAT_UNKNOWN;
|
||||
|
|
@ -90,6 +91,7 @@ static inline gs_color_format ConvertDXGITextureFormat(DXGI_FORMAT format)
|
|||
switch ((unsigned long)format) {
|
||||
case DXGI_FORMAT_A8_UNORM: return GS_A8;
|
||||
case DXGI_FORMAT_R8_UNORM: return GS_R8;
|
||||
case DXGI_FORMAT_R8G8_UNORM: return GS_R8G8;
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM: return GS_RGBA;
|
||||
case DXGI_FORMAT_B8G8R8X8_UNORM: return GS_BGRX;
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM: return GS_BGRA;
|
||||
|
|
@ -267,7 +269,7 @@ struct gs_vertex_buffer : gs_obj {
|
|||
uvBuffers.clear();
|
||||
}
|
||||
|
||||
inline void Rebuild();
|
||||
void Rebuild();
|
||||
|
||||
gs_vertex_buffer(gs_device_t *device, struct gs_vb_data *data,
|
||||
uint32_t flags);
|
||||
|
|
@ -294,7 +296,7 @@ struct gs_index_buffer : gs_obj {
|
|||
|
||||
void InitBuffer();
|
||||
|
||||
inline void Rebuild(ID3D11Device *dev);
|
||||
void Rebuild(ID3D11Device *dev);
|
||||
|
||||
inline void Release() {indexBuffer.Release();}
|
||||
|
||||
|
|
@ -310,7 +312,7 @@ struct gs_texture : gs_obj {
|
|||
ComPtr<ID3D11ShaderResourceView> shaderRes;
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC resourceDesc = {};
|
||||
|
||||
inline void Rebuild(ID3D11Device *dev);
|
||||
void Rebuild(ID3D11Device *dev);
|
||||
|
||||
inline gs_texture(gs_texture_type type, uint32_t levels,
|
||||
gs_color_format format)
|
||||
|
|
@ -344,13 +346,19 @@ struct gs_texture_2d : gs_texture {
|
|||
ComPtr<IDXGISurface1> gdiSurface;
|
||||
|
||||
uint32_t width = 0, height = 0;
|
||||
uint32_t flags = 0;
|
||||
DXGI_FORMAT dxgiFormat = DXGI_FORMAT_UNKNOWN;
|
||||
bool isRenderTarget = false;
|
||||
bool isGDICompatible = false;
|
||||
bool isDynamic = false;
|
||||
bool isShared = false;
|
||||
bool genMipmaps = false;
|
||||
uint32_t sharedHandle = 0;
|
||||
uint32_t sharedHandle = GS_INVALID_HANDLE;
|
||||
|
||||
gs_texture_2d *pairedNV12texture = nullptr;
|
||||
bool nv12 = false;
|
||||
bool chroma = false;
|
||||
bool acquired = false;
|
||||
|
||||
vector<vector<uint8_t>> data;
|
||||
vector<D3D11_SUBRESOURCE_DATA> srd;
|
||||
|
|
@ -361,9 +369,12 @@ struct gs_texture_2d : gs_texture {
|
|||
void InitResourceView();
|
||||
void InitRenderTargets();
|
||||
void BackupTexture(const uint8_t **data);
|
||||
void GetSharedHandle(IDXGIResource *dxgi_res);
|
||||
|
||||
void RebuildSharedTextureFallback();
|
||||
inline void Rebuild(ID3D11Device *dev);
|
||||
void Rebuild(ID3D11Device *dev);
|
||||
void RebuildNV12_Y(ID3D11Device *dev);
|
||||
void RebuildNV12_UV(ID3D11Device *dev);
|
||||
|
||||
inline void Release()
|
||||
{
|
||||
|
|
@ -382,8 +393,11 @@ struct gs_texture_2d : gs_texture {
|
|||
gs_texture_2d(gs_device_t *device, uint32_t width, uint32_t height,
|
||||
gs_color_format colorFormat, uint32_t levels,
|
||||
const uint8_t **data, uint32_t flags,
|
||||
gs_texture_type type, bool gdiCompatible, bool shared);
|
||||
gs_texture_type type, bool gdiCompatible,
|
||||
bool nv12 = false);
|
||||
|
||||
gs_texture_2d(gs_device_t *device, ID3D11Texture2D *nv12,
|
||||
uint32_t flags);
|
||||
gs_texture_2d(gs_device_t *device, uint32_t handle);
|
||||
};
|
||||
|
||||
|
|
@ -400,7 +414,7 @@ struct gs_zstencil_buffer : gs_obj {
|
|||
|
||||
void InitBuffer();
|
||||
|
||||
inline void Rebuild(ID3D11Device *dev);
|
||||
void Rebuild(ID3D11Device *dev);
|
||||
|
||||
inline void Release()
|
||||
{
|
||||
|
|
@ -427,7 +441,7 @@ struct gs_stage_surface : gs_obj {
|
|||
gs_color_format format;
|
||||
DXGI_FORMAT dxgiFormat;
|
||||
|
||||
inline void Rebuild(ID3D11Device *dev);
|
||||
void Rebuild(ID3D11Device *dev);
|
||||
|
||||
inline void Release()
|
||||
{
|
||||
|
|
@ -436,6 +450,7 @@ struct gs_stage_surface : gs_obj {
|
|||
|
||||
gs_stage_surface(gs_device_t *device, uint32_t width, uint32_t height,
|
||||
gs_color_format colorFormat);
|
||||
gs_stage_surface(gs_device_t *device, uint32_t width, uint32_t height);
|
||||
};
|
||||
|
||||
struct gs_sampler_state : gs_obj {
|
||||
|
|
@ -443,7 +458,7 @@ struct gs_sampler_state : gs_obj {
|
|||
D3D11_SAMPLER_DESC sd = {};
|
||||
gs_sampler_info info;
|
||||
|
||||
inline void Rebuild(ID3D11Device *dev);
|
||||
void Rebuild(ID3D11Device *dev);
|
||||
|
||||
inline void Release() {state.Release();}
|
||||
|
||||
|
|
@ -532,7 +547,7 @@ struct gs_vertex_shader : gs_shader {
|
|||
bool hasTangents;
|
||||
uint32_t nTexUnits;
|
||||
|
||||
inline void Rebuild(ID3D11Device *dev);
|
||||
void Rebuild(ID3D11Device *dev);
|
||||
|
||||
inline void Release()
|
||||
{
|
||||
|
|
@ -579,7 +594,7 @@ struct gs_pixel_shader : gs_shader {
|
|||
ComPtr<ID3D11PixelShader> shader;
|
||||
vector<unique_ptr<ShaderSampler>> samplers;
|
||||
|
||||
inline void Rebuild(ID3D11Device *dev);
|
||||
void Rebuild(ID3D11Device *dev);
|
||||
|
||||
inline void Release()
|
||||
{
|
||||
|
|
@ -615,7 +630,7 @@ struct gs_swap_chain : gs_obj {
|
|||
void Resize(uint32_t cx, uint32_t cy);
|
||||
void Init();
|
||||
|
||||
inline void Rebuild(ID3D11Device *dev);
|
||||
void Rebuild(ID3D11Device *dev);
|
||||
|
||||
inline void Release()
|
||||
{
|
||||
|
|
@ -644,7 +659,7 @@ struct BlendState {
|
|||
srcFactorC (GS_BLEND_SRCALPHA),
|
||||
destFactorC (GS_BLEND_INVSRCALPHA),
|
||||
srcFactorA (GS_BLEND_ONE),
|
||||
destFactorA (GS_BLEND_ONE),
|
||||
destFactorA (GS_BLEND_INVSRCALPHA),
|
||||
redEnabled (true),
|
||||
greenEnabled (true),
|
||||
blueEnabled (true),
|
||||
|
|
@ -662,7 +677,7 @@ struct SavedBlendState : BlendState {
|
|||
ComPtr<ID3D11BlendState> state;
|
||||
D3D11_BLEND_DESC bd;
|
||||
|
||||
inline void Rebuild(ID3D11Device *dev);
|
||||
void Rebuild(ID3D11Device *dev);
|
||||
|
||||
inline void Release()
|
||||
{
|
||||
|
|
@ -719,7 +734,7 @@ struct SavedZStencilState : ZStencilState {
|
|||
ComPtr<ID3D11DepthStencilState> state;
|
||||
D3D11_DEPTH_STENCIL_DESC dsd;
|
||||
|
||||
inline void Rebuild(ID3D11Device *dev);
|
||||
void Rebuild(ID3D11Device *dev);
|
||||
|
||||
inline void Release()
|
||||
{
|
||||
|
|
@ -754,7 +769,7 @@ struct SavedRasterState : RasterState {
|
|||
ComPtr<ID3D11RasterizerState> state;
|
||||
D3D11_RASTERIZER_DESC rd;
|
||||
|
||||
inline void Rebuild(ID3D11Device *dev);
|
||||
void Rebuild(ID3D11Device *dev);
|
||||
|
||||
inline void Release()
|
||||
{
|
||||
|
|
@ -779,6 +794,7 @@ struct gs_device {
|
|||
ComPtr<ID3D11Device> device;
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
uint32_t adpIdx = 0;
|
||||
bool nv12Supported = false;
|
||||
|
||||
gs_texture_2d *curRenderTarget = nullptr;
|
||||
gs_zstencil_buffer *curZStencilBuffer = nullptr;
|
||||
|
|
@ -845,6 +861,11 @@ struct gs_device {
|
|||
|
||||
void RebuildDevice();
|
||||
|
||||
bool HasBadNV12Output();
|
||||
|
||||
gs_device(uint32_t adapterIdx);
|
||||
~gs_device();
|
||||
};
|
||||
|
||||
extern "C" EXPORT int device_texture_acquire_sync(gs_texture_t *tex,
|
||||
uint64_t key, uint32_t ms);
|
||||
|
|
|
|||
|
|
@ -71,6 +71,20 @@ void gs_texture_2d::BackupTexture(const uint8_t **data)
|
|||
}
|
||||
}
|
||||
|
||||
void gs_texture_2d::GetSharedHandle(IDXGIResource *dxgi_res)
|
||||
{
|
||||
HANDLE handle;
|
||||
HRESULT hr;
|
||||
|
||||
hr = dxgi_res->GetSharedHandle(&handle);
|
||||
if (FAILED(hr)) {
|
||||
blog(LOG_WARNING, "GetSharedHandle: Failed to "
|
||||
"get shared handle: %08lX", hr);
|
||||
} else {
|
||||
sharedHandle = (uint32_t)(uintptr_t)handle;
|
||||
}
|
||||
}
|
||||
|
||||
void gs_texture_2d::InitTexture(const uint8_t **data)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
|
@ -80,7 +94,7 @@ void gs_texture_2d::InitTexture(const uint8_t **data)
|
|||
td.Height = height;
|
||||
td.MipLevels = genMipmaps ? 0 : levels;
|
||||
td.ArraySize = type == GS_TEXTURE_CUBE ? 6 : 1;
|
||||
td.Format = dxgiFormat;
|
||||
td.Format = nv12 ? DXGI_FORMAT_NV12 : dxgiFormat;
|
||||
td.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
td.SampleDesc.Count = 1;
|
||||
td.CPUAccessFlags = isDynamic ? D3D11_CPU_ACCESS_WRITE : 0;
|
||||
|
|
@ -96,6 +110,11 @@ void gs_texture_2d::InitTexture(const uint8_t **data)
|
|||
if (isGDICompatible)
|
||||
td.MiscFlags |= D3D11_RESOURCE_MISC_GDI_COMPATIBLE;
|
||||
|
||||
if ((flags & GS_SHARED_KM_TEX) != 0)
|
||||
td.MiscFlags |= D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
|
||||
else if ((flags & GS_SHARED_TEX) != 0)
|
||||
td.MiscFlags |= D3D11_RESOURCE_MISC_SHARED;
|
||||
|
||||
if (data) {
|
||||
BackupTexture(data);
|
||||
InitSRD(srd);
|
||||
|
|
@ -112,6 +131,36 @@ void gs_texture_2d::InitTexture(const uint8_t **data)
|
|||
if (FAILED(hr))
|
||||
throw HRError("Failed to create GDI surface", hr);
|
||||
}
|
||||
|
||||
if (isShared) {
|
||||
ComPtr<IDXGIResource> dxgi_res;
|
||||
|
||||
texture->SetEvictionPriority(DXGI_RESOURCE_PRIORITY_MAXIMUM);
|
||||
|
||||
hr = texture->QueryInterface(__uuidof(IDXGIResource),
|
||||
(void**)&dxgi_res);
|
||||
if (FAILED(hr)) {
|
||||
blog(LOG_WARNING, "InitTexture: Failed to query "
|
||||
"interface: %08lX", hr);
|
||||
} else {
|
||||
GetSharedHandle(dxgi_res);
|
||||
|
||||
if (flags & GS_SHARED_KM_TEX) {
|
||||
ComPtr<IDXGIKeyedMutex> km;
|
||||
hr = texture->QueryInterface(
|
||||
__uuidof(IDXGIKeyedMutex),
|
||||
(void**)&km);
|
||||
if (FAILED(hr)) {
|
||||
throw HRError("Failed to query "
|
||||
"IDXGIKeyedMutex",
|
||||
hr);
|
||||
}
|
||||
|
||||
km->AcquireSync(0, INFINITE);
|
||||
acquired = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gs_texture_2d::InitResourceView()
|
||||
|
|
@ -123,10 +172,12 @@ void gs_texture_2d::InitResourceView()
|
|||
|
||||
if (type == GS_TEXTURE_CUBE) {
|
||||
resourceDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
|
||||
resourceDesc.TextureCube.MipLevels = genMipmaps ? -1 : 1;
|
||||
resourceDesc.TextureCube.MipLevels =
|
||||
genMipmaps || !levels ? -1 : levels;
|
||||
} else {
|
||||
resourceDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
resourceDesc.Texture2D.MipLevels = genMipmaps ? -1 : 1;
|
||||
resourceDesc.Texture2D.MipLevels =
|
||||
genMipmaps || !levels ? -1 : levels;
|
||||
}
|
||||
|
||||
hr = device->device->CreateShaderResourceView(texture, &resourceDesc,
|
||||
|
|
@ -139,7 +190,12 @@ void gs_texture_2d::InitRenderTargets()
|
|||
{
|
||||
HRESULT hr;
|
||||
if (type == GS_TEXTURE_2D) {
|
||||
hr = device->device->CreateRenderTargetView(texture, NULL,
|
||||
D3D11_RENDER_TARGET_VIEW_DESC rtv;
|
||||
rtv.Format = dxgiFormat;
|
||||
rtv.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||
rtv.Texture2D.MipSlice = 0;
|
||||
|
||||
hr = device->device->CreateRenderTargetView(texture, &rtv,
|
||||
renderTarget[0].Assign());
|
||||
if (FAILED(hr))
|
||||
throw HRError("Failed to create render target view",
|
||||
|
|
@ -162,20 +218,25 @@ void gs_texture_2d::InitRenderTargets()
|
|||
}
|
||||
}
|
||||
|
||||
#define SHARED_FLAGS (GS_SHARED_TEX | GS_SHARED_KM_TEX)
|
||||
|
||||
gs_texture_2d::gs_texture_2d(gs_device_t *device, uint32_t width,
|
||||
uint32_t height, gs_color_format colorFormat, uint32_t levels,
|
||||
const uint8_t **data, uint32_t flags, gs_texture_type type,
|
||||
bool gdiCompatible, bool shared)
|
||||
const uint8_t **data, uint32_t flags_, gs_texture_type type,
|
||||
bool gdiCompatible, bool nv12_)
|
||||
: gs_texture (device, gs_type::gs_texture_2d, type, levels,
|
||||
colorFormat),
|
||||
width (width),
|
||||
height (height),
|
||||
flags (flags_),
|
||||
dxgiFormat (ConvertGSTextureFormat(format)),
|
||||
isRenderTarget ((flags & GS_RENDER_TARGET) != 0),
|
||||
isRenderTarget ((flags_ & GS_RENDER_TARGET) != 0),
|
||||
isGDICompatible (gdiCompatible),
|
||||
isDynamic ((flags & GS_DYNAMIC) != 0),
|
||||
isShared (shared),
|
||||
genMipmaps ((flags & GS_BUILD_MIPMAPS) != 0)
|
||||
isDynamic ((flags_ & GS_DYNAMIC) != 0),
|
||||
isShared ((flags_ & SHARED_FLAGS) != 0),
|
||||
genMipmaps ((flags_ & GS_BUILD_MIPMAPS) != 0),
|
||||
sharedHandle (GS_INVALID_HANDLE),
|
||||
nv12 (nv12_)
|
||||
{
|
||||
InitTexture(data);
|
||||
InitResourceView();
|
||||
|
|
@ -184,6 +245,33 @@ gs_texture_2d::gs_texture_2d(gs_device_t *device, uint32_t width,
|
|||
InitRenderTargets();
|
||||
}
|
||||
|
||||
gs_texture_2d::gs_texture_2d(gs_device_t *device, ID3D11Texture2D *nv12tex,
|
||||
uint32_t flags_)
|
||||
: gs_texture (device, gs_type::gs_texture_2d, GS_TEXTURE_2D),
|
||||
isRenderTarget ((flags_ & GS_RENDER_TARGET) != 0),
|
||||
isDynamic ((flags_ & GS_DYNAMIC) != 0),
|
||||
isShared ((flags_ & SHARED_FLAGS) != 0),
|
||||
genMipmaps ((flags_ & GS_BUILD_MIPMAPS) != 0),
|
||||
nv12 (true)
|
||||
{
|
||||
texture = nv12tex;
|
||||
texture->GetDesc(&td);
|
||||
|
||||
this->type = GS_TEXTURE_2D;
|
||||
this->format = GS_R8G8;
|
||||
this->flags = flags_;
|
||||
this->levels = 1;
|
||||
this->device = device;
|
||||
this->chroma = true;
|
||||
this->width = td.Width / 2;
|
||||
this->height = td.Height / 2;
|
||||
this->dxgiFormat = DXGI_FORMAT_R8G8_UNORM;
|
||||
|
||||
InitResourceView();
|
||||
if (isRenderTarget)
|
||||
InitRenderTargets();
|
||||
}
|
||||
|
||||
gs_texture_2d::gs_texture_2d(gs_device_t *device, uint32_t handle)
|
||||
: gs_texture (device, gs_type::gs_texture_2d,
|
||||
GS_TEXTURE_2D),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue