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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue