|
@@ -78,7 +78,7 @@ static inline void make_swap_desc(DXGI_SWAP_CHAIN_DESC &desc,
|
|
{
|
|
{
|
|
memset(&desc, 0, sizeof(desc));
|
|
memset(&desc, 0, sizeof(desc));
|
|
desc.BufferCount = data->num_backbuffers;
|
|
desc.BufferCount = data->num_backbuffers;
|
|
- desc.BufferDesc.Format = ConvertGSTextureFormat(data->format);
|
|
|
|
|
|
+ desc.BufferDesc.Format = ConvertGSTextureFormatView(data->format);
|
|
desc.BufferDesc.Width = data->cx;
|
|
desc.BufferDesc.Width = data->cx;
|
|
desc.BufferDesc.Height = data->cy;
|
|
desc.BufferDesc.Height = data->cy;
|
|
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
|
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
|
@@ -99,10 +99,24 @@ void gs_swap_chain::InitTarget(uint32_t cx, uint32_t cy)
|
|
if (FAILED(hr))
|
|
if (FAILED(hr))
|
|
throw HRError("Failed to get swap buffer texture", hr);
|
|
throw HRError("Failed to get swap buffer texture", hr);
|
|
|
|
|
|
|
|
+ D3D11_RENDER_TARGET_VIEW_DESC rtv;
|
|
|
|
+ rtv.Format = target.dxgiFormatView;
|
|
|
|
+ rtv.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
|
|
|
+ rtv.Texture2D.MipSlice = 0;
|
|
hr = device->device->CreateRenderTargetView(
|
|
hr = device->device->CreateRenderTargetView(
|
|
- target.texture, NULL, target.renderTarget[0].Assign());
|
|
|
|
|
|
+ target.texture, &rtv, target.renderTarget[0].Assign());
|
|
if (FAILED(hr))
|
|
if (FAILED(hr))
|
|
- throw HRError("Failed to create swap render target view", hr);
|
|
|
|
|
|
+ throw HRError("Failed to create swap RTV", hr);
|
|
|
|
+ if (target.dxgiFormatView == target.dxgiFormatViewLinear) {
|
|
|
|
+ target.renderTargetLinear[0] = target.renderTarget[0];
|
|
|
|
+ } else {
|
|
|
|
+ rtv.Format = target.dxgiFormatViewLinear;
|
|
|
|
+ hr = device->device->CreateRenderTargetView(
|
|
|
|
+ target.texture, &rtv,
|
|
|
|
+ target.renderTargetLinear[0].Assign());
|
|
|
|
+ if (FAILED(hr))
|
|
|
|
+ throw HRError("Failed to create linear swap RTV", hr);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
void gs_swap_chain::InitZStencilBuffer(uint32_t cx, uint32_t cy)
|
|
void gs_swap_chain::InitZStencilBuffer(uint32_t cx, uint32_t cy)
|
|
@@ -125,6 +139,7 @@ void gs_swap_chain::Resize(uint32_t cx, uint32_t cy)
|
|
|
|
|
|
target.texture.Clear();
|
|
target.texture.Clear();
|
|
target.renderTarget[0].Clear();
|
|
target.renderTarget[0].Clear();
|
|
|
|
+ target.renderTargetLinear[0].Clear();
|
|
zs.texture.Clear();
|
|
zs.texture.Clear();
|
|
zs.view.Clear();
|
|
zs.view.Clear();
|
|
|
|
|
|
@@ -139,7 +154,7 @@ void gs_swap_chain::Resize(uint32_t cx, uint32_t cy)
|
|
cy = clientRect.bottom;
|
|
cy = clientRect.bottom;
|
|
}
|
|
}
|
|
|
|
|
|
- hr = swap->ResizeBuffers(numBuffers, cx, cy, target.dxgiFormat, 0);
|
|
|
|
|
|
+ hr = swap->ResizeBuffers(numBuffers, cx, cy, DXGI_FORMAT_UNKNOWN, 0);
|
|
if (FAILED(hr))
|
|
if (FAILED(hr))
|
|
throw HRError("Failed to resize swap buffers", hr);
|
|
throw HRError("Failed to resize swap buffers", hr);
|
|
|
|
|
|
@@ -152,7 +167,11 @@ void gs_swap_chain::Init()
|
|
target.device = device;
|
|
target.device = device;
|
|
target.isRenderTarget = true;
|
|
target.isRenderTarget = true;
|
|
target.format = initData.format;
|
|
target.format = initData.format;
|
|
- target.dxgiFormat = ConvertGSTextureFormat(initData.format);
|
|
|
|
|
|
+ target.dxgiFormatResource =
|
|
|
|
+ ConvertGSTextureFormatResource(initData.format);
|
|
|
|
+ target.dxgiFormatView = ConvertGSTextureFormatView(initData.format);
|
|
|
|
+ target.dxgiFormatViewLinear =
|
|
|
|
+ ConvertGSTextureFormatViewLinear(initData.format);
|
|
InitTarget(initData.cx, initData.cy);
|
|
InitTarget(initData.cx, initData.cy);
|
|
|
|
|
|
zs.device = device;
|
|
zs.device = device;
|
|
@@ -310,6 +329,7 @@ try {
|
|
UpdateBlendState();
|
|
UpdateBlendState();
|
|
UpdateRasterState();
|
|
UpdateRasterState();
|
|
UpdateZStencilState();
|
|
UpdateZStencilState();
|
|
|
|
+ FlushOutputViews();
|
|
context->Draw(4, 0);
|
|
context->Draw(4, 0);
|
|
|
|
|
|
device_set_viewport(this, 0, 0, NV12_CX / 2, NV12_CY / 2);
|
|
device_set_viewport(this, 0, 0, NV12_CX / 2, NV12_CY / 2);
|
|
@@ -318,6 +338,7 @@ try {
|
|
UpdateBlendState();
|
|
UpdateBlendState();
|
|
UpdateRasterState();
|
|
UpdateRasterState();
|
|
UpdateZStencilState();
|
|
UpdateZStencilState();
|
|
|
|
+ FlushOutputViews();
|
|
context->Draw(4, 0);
|
|
context->Draw(4, 0);
|
|
|
|
|
|
device_load_pixelshader(this, nullptr);
|
|
device_load_pixelshader(this, nullptr);
|
|
@@ -727,6 +748,30 @@ void gs_device::UpdateViewProjMatrix()
|
|
&curViewProjMatrix);
|
|
&curViewProjMatrix);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void gs_device::FlushOutputViews()
|
|
|
|
+{
|
|
|
|
+ if (curFramebufferInvalidate) {
|
|
|
|
+ ID3D11RenderTargetView *rtv = nullptr;
|
|
|
|
+ if (curRenderTarget) {
|
|
|
|
+ const int i = curRenderSide;
|
|
|
|
+ rtv = curFramebufferSrgb
|
|
|
|
+ ? curRenderTarget->renderTargetLinear[i]
|
|
|
|
+ .Get()
|
|
|
|
+ : curRenderTarget->renderTarget[i].Get();
|
|
|
|
+ if (!rtv) {
|
|
|
|
+ blog(LOG_ERROR,
|
|
|
|
+ "device_draw (D3D11): texture is not a render target");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ ID3D11DepthStencilView *dsv = nullptr;
|
|
|
|
+ if (curZStencilBuffer)
|
|
|
|
+ dsv = curZStencilBuffer->view;
|
|
|
|
+ context->OMSetRenderTargets(1, &rtv, dsv);
|
|
|
|
+ curFramebufferInvalidate = false;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
gs_device::gs_device(uint32_t adapterIdx)
|
|
gs_device::gs_device(uint32_t adapterIdx)
|
|
: curToplogy(D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED)
|
|
: curToplogy(D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED)
|
|
{
|
|
{
|
|
@@ -1045,18 +1090,9 @@ void device_resize(gs_device_t *device, uint32_t cx, uint32_t cy)
|
|
|
|
|
|
try {
|
|
try {
|
|
ID3D11RenderTargetView *renderView = NULL;
|
|
ID3D11RenderTargetView *renderView = NULL;
|
|
- ID3D11DepthStencilView *depthView = NULL;
|
|
|
|
- int i = device->curRenderSide;
|
|
|
|
-
|
|
|
|
- device->context->OMSetRenderTargets(1, &renderView, depthView);
|
|
|
|
|
|
+ device->context->OMSetRenderTargets(1, &renderView, NULL);
|
|
device->curSwapChain->Resize(cx, cy);
|
|
device->curSwapChain->Resize(cx, cy);
|
|
-
|
|
|
|
- if (device->curRenderTarget)
|
|
|
|
- renderView = device->curRenderTarget->renderTarget[i];
|
|
|
|
- if (device->curZStencilBuffer)
|
|
|
|
- depthView = device->curZStencilBuffer->view;
|
|
|
|
- device->context->OMSetRenderTargets(1, &renderView, depthView);
|
|
|
|
-
|
|
|
|
|
|
+ device->curFramebufferInvalidate = true;
|
|
} catch (const HRError &error) {
|
|
} catch (const HRError &error) {
|
|
blog(LOG_ERROR, "device_resize (D3D11): %s (%08lX)", error.str,
|
|
blog(LOG_ERROR, "device_resize (D3D11): %s (%08lX)", error.str,
|
|
error.hr);
|
|
error.hr);
|
|
@@ -1419,20 +1455,29 @@ void device_load_indexbuffer(gs_device_t *device, gs_indexbuffer_t *indexbuffer)
|
|
device->context->IASetIndexBuffer(buffer, format, 0);
|
|
device->context->IASetIndexBuffer(buffer, format, 0);
|
|
}
|
|
}
|
|
|
|
|
|
-void device_load_texture(gs_device_t *device, gs_texture_t *tex, int unit)
|
|
|
|
|
|
+static void device_load_texture_internal(gs_device_t *device, gs_texture_t *tex,
|
|
|
|
+ int unit,
|
|
|
|
+ ID3D11ShaderResourceView *view)
|
|
{
|
|
{
|
|
- ID3D11ShaderResourceView *view = NULL;
|
|
|
|
-
|
|
|
|
if (device->curTextures[unit] == tex)
|
|
if (device->curTextures[unit] == tex)
|
|
return;
|
|
return;
|
|
|
|
|
|
- if (tex)
|
|
|
|
- view = tex->shaderRes;
|
|
|
|
-
|
|
|
|
device->curTextures[unit] = tex;
|
|
device->curTextures[unit] = tex;
|
|
device->context->PSSetShaderResources(unit, 1, &view);
|
|
device->context->PSSetShaderResources(unit, 1, &view);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void device_load_texture(gs_device_t *device, gs_texture_t *tex, int unit)
|
|
|
|
+{
|
|
|
|
+ ID3D11ShaderResourceView *view = tex ? tex->shaderRes : NULL;
|
|
|
|
+ return device_load_texture_internal(device, tex, unit, view);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void device_load_texture_srgb(gs_device_t *device, gs_texture_t *tex, int unit)
|
|
|
|
+{
|
|
|
|
+ ID3D11ShaderResourceView *view = tex ? tex->shaderResLinear : NULL;
|
|
|
|
+ return device_load_texture_internal(device, tex, unit, view);
|
|
|
|
+}
|
|
|
|
+
|
|
void device_load_samplerstate(gs_device_t *device,
|
|
void device_load_samplerstate(gs_device_t *device,
|
|
gs_samplerstate_t *samplerstate, int unit)
|
|
gs_samplerstate_t *samplerstate, int unit)
|
|
{
|
|
{
|
|
@@ -1574,26 +1619,19 @@ void device_set_render_target(gs_device_t *device, gs_texture_t *tex,
|
|
return;
|
|
return;
|
|
|
|
|
|
if (tex && tex->type != GS_TEXTURE_2D) {
|
|
if (tex && tex->type != GS_TEXTURE_2D) {
|
|
- blog(LOG_ERROR, "device_set_render_target (D3D11): "
|
|
|
|
- "texture is not a 2D texture");
|
|
|
|
|
|
+ blog(LOG_ERROR,
|
|
|
|
+ "device_set_render_target (D3D11): texture is not a 2D texture");
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- gs_texture_2d *tex2d = static_cast<gs_texture_2d *>(tex);
|
|
|
|
- if (tex2d && !tex2d->renderTarget[0]) {
|
|
|
|
- blog(LOG_ERROR, "device_set_render_target (D3D11): "
|
|
|
|
- "texture is not a render target");
|
|
|
|
- return;
|
|
|
|
|
|
+ gs_texture_2d *const tex2d = static_cast<gs_texture_2d *>(tex);
|
|
|
|
+ if (device->curRenderTarget != tex2d || device->curRenderSide != 0 ||
|
|
|
|
+ device->curZStencilBuffer != zstencil) {
|
|
|
|
+ device->curRenderTarget = tex2d;
|
|
|
|
+ device->curRenderSide = 0;
|
|
|
|
+ device->curZStencilBuffer = zstencil;
|
|
|
|
+ device->curFramebufferInvalidate = true;
|
|
}
|
|
}
|
|
-
|
|
|
|
- ID3D11RenderTargetView *rt = tex2d ? tex2d->renderTarget[0].Get()
|
|
|
|
- : nullptr;
|
|
|
|
-
|
|
|
|
- device->curRenderTarget = tex2d;
|
|
|
|
- device->curRenderSide = 0;
|
|
|
|
- device->curZStencilBuffer = zstencil;
|
|
|
|
- device->context->OMSetRenderTargets(
|
|
|
|
- 1, &rt, zstencil ? zstencil->view : nullptr);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void device_set_cube_render_target(gs_device_t *device, gs_texture_t *tex,
|
|
void device_set_cube_render_target(gs_device_t *device, gs_texture_t *tex,
|
|
@@ -1619,19 +1657,27 @@ void device_set_cube_render_target(gs_device_t *device, gs_texture_t *tex,
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- gs_texture_2d *tex2d = static_cast<gs_texture_2d *>(tex);
|
|
|
|
- if (!tex2d->renderTarget[side]) {
|
|
|
|
- blog(LOG_ERROR, "device_set_cube_render_target (D3D11): "
|
|
|
|
- "texture is not a render target");
|
|
|
|
- return;
|
|
|
|
|
|
+ gs_texture_2d *const tex2d = static_cast<gs_texture_2d *>(tex);
|
|
|
|
+ if (device->curRenderTarget != tex2d || device->curRenderSide != side ||
|
|
|
|
+ device->curZStencilBuffer != zstencil) {
|
|
|
|
+ device->curRenderTarget = tex2d;
|
|
|
|
+ device->curRenderSide = side;
|
|
|
|
+ device->curZStencilBuffer = zstencil;
|
|
|
|
+ device->curFramebufferInvalidate = true;
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
|
|
- ID3D11RenderTargetView *rt = tex2d->renderTarget[0];
|
|
|
|
|
|
+void device_enable_framebuffer_srgb(gs_device_t *device, bool enable)
|
|
|
|
+{
|
|
|
|
+ if (device->curFramebufferSrgb != enable) {
|
|
|
|
+ device->curFramebufferSrgb = enable;
|
|
|
|
+ device->curFramebufferInvalidate = true;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
|
|
- device->curRenderTarget = tex2d;
|
|
|
|
- device->curRenderSide = side;
|
|
|
|
- device->curZStencilBuffer = zstencil;
|
|
|
|
- device->context->OMSetRenderTargets(1, &rt, zstencil->view);
|
|
|
|
|
|
+bool device_framebuffer_srgb_enabled(gs_device_t *device)
|
|
|
|
+{
|
|
|
|
+ return device->curFramebufferSrgb;
|
|
}
|
|
}
|
|
|
|
|
|
inline void gs_device::CopyTex(ID3D11Texture2D *dst, uint32_t dst_x,
|
|
inline void gs_device::CopyTex(ID3D11Texture2D *dst, uint32_t dst_x,
|
|
@@ -1780,6 +1826,8 @@ void device_draw(gs_device_t *device, enum gs_draw_mode draw_mode,
|
|
if (!device->curSwapChain && !device->curRenderTarget)
|
|
if (!device->curSwapChain && !device->curRenderTarget)
|
|
throw "No render target or swap chain to render to";
|
|
throw "No render target or swap chain to render to";
|
|
|
|
|
|
|
|
+ device->FlushOutputViews();
|
|
|
|
+
|
|
gs_effect_t *effect = gs_get_effect();
|
|
gs_effect_t *effect = gs_get_effect();
|
|
if (effect)
|
|
if (effect)
|
|
gs_effect_update_params(effect);
|
|
gs_effect_update_params(effect);
|
|
@@ -2589,9 +2637,10 @@ device_texture_create_gdi(gs_device_t *device, uint32_t width, uint32_t height)
|
|
{
|
|
{
|
|
gs_texture *texture = nullptr;
|
|
gs_texture *texture = nullptr;
|
|
try {
|
|
try {
|
|
- texture = new gs_texture_2d(device, width, height, GS_BGRA, 1,
|
|
|
|
- nullptr, GS_RENDER_TARGET,
|
|
|
|
- GS_TEXTURE_2D, true);
|
|
|
|
|
|
+ texture = new gs_texture_2d(device, width, height,
|
|
|
|
+ GS_BGRA_UNORM, 1, nullptr,
|
|
|
|
+ GS_RENDER_TARGET, GS_TEXTURE_2D,
|
|
|
|
+ true);
|
|
} catch (const HRError &error) {
|
|
} catch (const HRError &error) {
|
|
blog(LOG_ERROR, "device_texture_create_gdi (D3D11): %s (%08lX)",
|
|
blog(LOG_ERROR, "device_texture_create_gdi (D3D11): %s (%08lX)",
|
|
error.str, error.hr);
|
|
error.str, error.hr);
|