New upstream version 23.2.1+dfsg1

This commit is contained in:
Simon Chopin 2019-07-27 14:47:10 +02:00
parent cdc9a9fc87
commit b14f9eae6d
1017 changed files with 37232 additions and 11111 deletions

View file

@ -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;
}