mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-21 07:47:32 +09:00
[WIP] D3D11 gpu accel
This commit is contained in:
parent
b7c0ebfcd4
commit
25c4eb5efb
9 changed files with 339 additions and 0 deletions
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "TextureD3D11.h"
|
#include "TextureD3D11.h"
|
||||||
#include "CompositorD3D11Shaders.h"
|
#include "CompositorD3D11Shaders.h"
|
||||||
|
#include "GpuRasterD3D11.h"
|
||||||
|
|
||||||
#include "gfxWindowsPlatform.h"
|
#include "gfxWindowsPlatform.h"
|
||||||
#include "nsIWidget.h"
|
#include "nsIWidget.h"
|
||||||
|
|
@ -143,6 +144,7 @@ private:
|
||||||
|
|
||||||
CompositorD3D11::CompositorD3D11(CompositorBridgeParent* aParent, widget::CompositorWidget* aWidget)
|
CompositorD3D11::CompositorD3D11(CompositorBridgeParent* aParent, widget::CompositorWidget* aWidget)
|
||||||
: Compositor(aWidget, aParent)
|
: Compositor(aWidget, aParent)
|
||||||
|
, mGpuRasterViewport(false)
|
||||||
, mAttachments(nullptr)
|
, mAttachments(nullptr)
|
||||||
, mHwnd(nullptr)
|
, mHwnd(nullptr)
|
||||||
, mDisableSequenceForNextFrame(false)
|
, mDisableSequenceForNextFrame(false)
|
||||||
|
|
@ -199,6 +201,16 @@ CompositorD3D11::Initialize(nsCString* const out_failureReason)
|
||||||
|
|
||||||
mFeatureLevel = mDevice->GetFeatureLevel();
|
mFeatureLevel = mDevice->GetFeatureLevel();
|
||||||
|
|
||||||
|
D3D11_FEATURE_DATA_D3D11_OPTIONS options = {};
|
||||||
|
if (gfxPrefs::D3D11GpuRectangleFills() &&
|
||||||
|
mFeatureLevel >= D3D_FEATURE_LEVEL_10_0 &&
|
||||||
|
SUCCEEDED(mDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS,
|
||||||
|
&options, sizeof(options))) &&
|
||||||
|
options.ClearView) {
|
||||||
|
mContext->QueryInterface(__uuidof(ID3D11DeviceContext1),
|
||||||
|
getter_AddRefs(mGpuRasterContext));
|
||||||
|
}
|
||||||
|
|
||||||
mHwnd = mWidget->AsWindows()->GetHwnd();
|
mHwnd = mWidget->AsWindows()->GetHwnd();
|
||||||
|
|
||||||
memset(&mVSConstants, 0, sizeof(VertexShaderConstants));
|
memset(&mVSConstants, 0, sizeof(VertexShaderConstants));
|
||||||
|
|
@ -656,6 +668,20 @@ CompositorD3D11::GetPSForEffect(Effect* aEffect, MaskType aMaskType)
|
||||||
void
|
void
|
||||||
CompositorD3D11::ClearRect(const gfx::Rect& aRect)
|
CompositorD3D11::ClearRect(const gfx::Rect& aRect)
|
||||||
{
|
{
|
||||||
|
if (mGpuRasterContext && mGpuRasterViewport && mCurrentRT &&
|
||||||
|
!mCurrentRT->HasComplexProjection()) {
|
||||||
|
GpuRasterRect rect = { aRect.x, aRect.y, aRect.XMost(), aRect.YMost() };
|
||||||
|
IntSize size = mCurrentRT->GetSize();
|
||||||
|
D3D11_RECT clip = { 0, 0, size.width, size.height };
|
||||||
|
const float clear[4] = { 0, 0, 0, 0 };
|
||||||
|
if (GpuRasterD3D11FillRect(mGpuRasterContext, mCurrentRT->mRTView,
|
||||||
|
size.width, size.height, &rect, &clip, clear)) {
|
||||||
|
// BeginFrame relies on ClearRect to establish premultiplied blending.
|
||||||
|
mContext->OMSetBlendState(mAttachments->mPremulBlendState, sBlendFactor, 0xFFFFFFFF);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mContext->OMSetBlendState(mAttachments->mDisabledBlendState, sBlendFactor, 0xFFFFFFFF);
|
mContext->OMSetBlendState(mAttachments->mDisabledBlendState, sBlendFactor, 0xFFFFFFFF);
|
||||||
|
|
||||||
Matrix4x4 identity;
|
Matrix4x4 identity;
|
||||||
|
|
@ -736,6 +762,39 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
|
||||||
|
|
||||||
MOZ_ASSERT(mCurrentRT, "No render target");
|
MOZ_ASSERT(mCurrentRT, "No render target");
|
||||||
|
|
||||||
|
// Opaque, integer-aligned translated rectangles can be filled directly by
|
||||||
|
// the GPU without shader binding or per-quad constant-buffer uploads.
|
||||||
|
if (mGpuRasterContext && mGpuRasterViewport && !mCurrentRT->HasComplexProjection() &&
|
||||||
|
aEffectChain.mPrimaryEffect->mType == EffectTypes::SOLID_COLOR &&
|
||||||
|
!aEffectChain.mSecondaryEffects[EffectTypes::MASK] &&
|
||||||
|
!aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE] &&
|
||||||
|
aOpacity == 1.0f && aTransform.Is2D() && aTransform.As2D().IsTranslation()) {
|
||||||
|
const Color& color = static_cast<EffectSolidColor*>(aEffectChain.mPrimaryEffect.get())->mColor;
|
||||||
|
if (color.a == 1.0f) {
|
||||||
|
IntPoint origin = mCurrentRT->GetOrigin();
|
||||||
|
// Transform both edges in the shader's order before subtracting the
|
||||||
|
// target origin; moving x/y and then adding width/height can round
|
||||||
|
// differently for large coordinates.
|
||||||
|
float left = aRect.x + aTransform._41;
|
||||||
|
float right = aRect.XMost() + aTransform._41;
|
||||||
|
float top = aRect.y + aTransform._42;
|
||||||
|
float bottom = aRect.YMost() + aTransform._42;
|
||||||
|
GpuRasterRect rect = { left - origin.x, top - origin.y,
|
||||||
|
right - origin.x, bottom - origin.y };
|
||||||
|
IntRect clipRect = aClipRect;
|
||||||
|
if (mCurrentRT == mDefaultRT) {
|
||||||
|
clipRect = clipRect.Intersect(mCurrentClip);
|
||||||
|
}
|
||||||
|
D3D11_RECT clip = { clipRect.x, clipRect.y, clipRect.XMost(), clipRect.YMost() };
|
||||||
|
IntSize size = mCurrentRT->GetSize();
|
||||||
|
const float fill[4] = { color.r, color.g, color.b, color.a };
|
||||||
|
if (GpuRasterD3D11FillRect(mGpuRasterContext, mCurrentRT->mRTView,
|
||||||
|
size.width, size.height, &rect, &clip, fill)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(&mVSConstants.layerTransform, &aTransform._11, 64);
|
memcpy(&mVSConstants.layerTransform, &aTransform._11, 64);
|
||||||
IntPoint origin = mCurrentRT->GetOrigin();
|
IntPoint origin = mCurrentRT->GetOrigin();
|
||||||
mVSConstants.renderTargetOffset[0] = origin.x;
|
mVSConstants.renderTargetOffset[0] = origin.x;
|
||||||
|
|
@ -1193,6 +1252,7 @@ CompositorD3D11::PrepareViewport(const gfx::IntSize& aSize)
|
||||||
projection._33 = 0.0f;
|
projection._33 = 0.0f;
|
||||||
|
|
||||||
PrepareViewport(aSize, projection, 0.0f, 1.0f);
|
PrepareViewport(aSize, projection, 0.0f, 1.0f);
|
||||||
|
mGpuRasterViewport = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1213,6 +1273,7 @@ CompositorD3D11::PrepareViewport(const gfx::IntSize& aSize,
|
||||||
const gfx::Matrix4x4& aProjection,
|
const gfx::Matrix4x4& aProjection,
|
||||||
float aZNear, float aZFar)
|
float aZNear, float aZFar)
|
||||||
{
|
{
|
||||||
|
mGpuRasterViewport = false;
|
||||||
D3D11_VIEWPORT viewport;
|
D3D11_VIEWPORT viewport;
|
||||||
viewport.MaxDepth = aZFar;
|
viewport.MaxDepth = aZFar;
|
||||||
viewport.MinDepth = aZNear;
|
viewport.MinDepth = aZNear;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include "mozilla/layers/Compositor.h"
|
#include "mozilla/layers/Compositor.h"
|
||||||
#include "TextureD3D11.h"
|
#include "TextureD3D11.h"
|
||||||
#include <d3d11.h>
|
#include <d3d11.h>
|
||||||
|
#include <d3d11_1.h>
|
||||||
|
|
||||||
class nsWidget;
|
class nsWidget;
|
||||||
|
|
||||||
|
|
@ -174,6 +175,8 @@ private:
|
||||||
RefPtr<ID3D11ShaderResourceView>* aOutView);
|
RefPtr<ID3D11ShaderResourceView>* aOutView);
|
||||||
|
|
||||||
RefPtr<ID3D11DeviceContext> mContext;
|
RefPtr<ID3D11DeviceContext> mContext;
|
||||||
|
RefPtr<ID3D11DeviceContext1> mGpuRasterContext;
|
||||||
|
bool mGpuRasterViewport;
|
||||||
RefPtr<ID3D11Device> mDevice;
|
RefPtr<ID3D11Device> mDevice;
|
||||||
RefPtr<IDXGISwapChain> mSwapChain;
|
RefPtr<IDXGISwapChain> mSwapChain;
|
||||||
RefPtr<CompositingRenderTargetD3D11> mDefaultRT;
|
RefPtr<CompositingRenderTargetD3D11> mDefaultRT;
|
||||||
|
|
|
||||||
84
gfx/layers/d3d11/GpuRasterD3D11.c
Normal file
84
gfx/layers/d3d11/GpuRasterD3D11.c
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#define COBJMACROS
|
||||||
|
#include "GpuRasterD3D11.h"
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
IntegerEdge(double value)
|
||||||
|
{
|
||||||
|
/* Ordered comparisons reject NaNs and infinities before integer conversion. */
|
||||||
|
return value >= LONG_MIN && value <= LONG_MAX && value == (LONG)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
GpuRasterD3D11ClipRect(const GpuRasterRect* rect, const D3D11_RECT* clip,
|
||||||
|
LONG width, LONG height, D3D11_RECT* result)
|
||||||
|
{
|
||||||
|
LONG left, top, right, bottom;
|
||||||
|
if (!rect || !clip || !result || width <= 0 || height <= 0 ||
|
||||||
|
!IntegerEdge(rect->left) || !IntegerEdge(rect->top) ||
|
||||||
|
!IntegerEdge(rect->right) || !IntegerEdge(rect->bottom) ||
|
||||||
|
rect->right < rect->left || rect->bottom < rect->top) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
left = (LONG)rect->left;
|
||||||
|
top = (LONG)rect->top;
|
||||||
|
right = (LONG)rect->right;
|
||||||
|
bottom = (LONG)rect->bottom;
|
||||||
|
if (left < clip->left) left = clip->left;
|
||||||
|
if (top < clip->top) top = clip->top;
|
||||||
|
if (right > clip->right) right = clip->right;
|
||||||
|
if (bottom > clip->bottom) bottom = clip->bottom;
|
||||||
|
if (left < 0) left = 0;
|
||||||
|
if (top < 0) top = 0;
|
||||||
|
if (right > width) right = width;
|
||||||
|
if (bottom > height) bottom = height;
|
||||||
|
|
||||||
|
if (right <= left || bottom <= top) {
|
||||||
|
result->left = result->top = result->right = result->bottom = 0;
|
||||||
|
} else {
|
||||||
|
result->left = left;
|
||||||
|
result->top = top;
|
||||||
|
result->right = right;
|
||||||
|
result->bottom = bottom;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
GpuRasterD3D11FillRect(ID3D11DeviceContext1* context,
|
||||||
|
ID3D11RenderTargetView* target,
|
||||||
|
LONG width, LONG height,
|
||||||
|
const GpuRasterRect* rect, const D3D11_RECT* clip,
|
||||||
|
const float color[4])
|
||||||
|
{
|
||||||
|
D3D11_RECT clipped;
|
||||||
|
D3D11_RENDER_TARGET_VIEW_DESC desc;
|
||||||
|
unsigned i;
|
||||||
|
if (!context || !target || !color ||
|
||||||
|
!GpuRasterD3D11ClipRect(rect, clip, width, height, &clipped)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
for (i = 0; i < 4; ++i) {
|
||||||
|
if (!(color[i] >= 0.0f && color[i] <= 1.0f)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D11RenderTargetView_GetDesc(target, &desc);
|
||||||
|
if ((desc.Format != DXGI_FORMAT_B8G8R8A8_UNORM &&
|
||||||
|
desc.Format != DXGI_FORMAT_R8G8B8A8_UNORM) ||
|
||||||
|
desc.ViewDimension != D3D11_RTV_DIMENSION_TEXTURE2D ||
|
||||||
|
desc.Texture2D.MipSlice != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (clipped.right != clipped.left && clipped.bottom != clipped.top) {
|
||||||
|
ID3D11DeviceContext1_ClearView(context, (ID3D11View*)target, color, &clipped, 1);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
36
gfx/layers/d3d11/GpuRasterD3D11.h
Normal file
36
gfx/layers/d3d11/GpuRasterD3D11.h
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef GFX_GPU_RASTER_D3D11_H
|
||||||
|
#define GFX_GPU_RASTER_D3D11_H
|
||||||
|
|
||||||
|
#include <d3d11_1.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Device-space edges. Fractional or non-finite edges require normal drawing. */
|
||||||
|
typedef struct GpuRasterRect {
|
||||||
|
double left, top, right, bottom;
|
||||||
|
} GpuRasterRect;
|
||||||
|
|
||||||
|
/* FALSE means unsupported input; TRUE may produce an empty clipped rectangle. */
|
||||||
|
BOOL GpuRasterD3D11ClipRect(const GpuRasterRect* rect, const D3D11_RECT* clip,
|
||||||
|
LONG width, LONG height, D3D11_RECT* result);
|
||||||
|
|
||||||
|
/* Source replacement, not alpha blending. The caller must check ClearView
|
||||||
|
* device support and supply the dimensions of the render target. No pipeline
|
||||||
|
* bindings are changed. FALSE leaves the target untouched for shader fallback. */
|
||||||
|
BOOL GpuRasterD3D11FillRect(ID3D11DeviceContext1* context,
|
||||||
|
ID3D11RenderTargetView* target,
|
||||||
|
LONG width, LONG height,
|
||||||
|
const GpuRasterRect* rect, const D3D11_RECT* clip,
|
||||||
|
const float color[4]);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -80,6 +80,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||||
]
|
]
|
||||||
SOURCES += [
|
SOURCES += [
|
||||||
'd3d11/CompositorD3D11.cpp',
|
'd3d11/CompositorD3D11.cpp',
|
||||||
|
'd3d11/GpuRasterD3D11.c',
|
||||||
'd3d11/ReadbackManagerD3D11.cpp',
|
'd3d11/ReadbackManagerD3D11.cpp',
|
||||||
]
|
]
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
|
|
|
||||||
148
gfx/tests/gtest/TestGpuRasterD3D11.cpp
Normal file
148
gfx/tests/gtest/TestGpuRasterD3D11.cpp
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef NOMINMAX
|
||||||
|
# define NOMINMAX
|
||||||
|
#endif
|
||||||
|
#include "d3d11/GpuRasterD3D11.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#ifndef GPU_RASTER_STANDALONE
|
||||||
|
# include "gtest/gtest.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CHECK_GPU(condition) do { \
|
||||||
|
if (!(condition)) { fprintf(stderr, "GPU rectangle test failed at line %d\n", __LINE__); \
|
||||||
|
return false; } \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static bool TestGpuRectangleClipping()
|
||||||
|
{
|
||||||
|
D3D11_RECT clip = { 2, 3, 12, 13 }, output;
|
||||||
|
GpuRasterRect rect = { -4, -5, 20, 21 };
|
||||||
|
CHECK_GPU(GpuRasterD3D11ClipRect(&rect, &clip, 10, 10, &output));
|
||||||
|
CHECK_GPU(output.left == 2 && output.top == 3 && output.right == 10 && output.bottom == 10);
|
||||||
|
rect = { 20, 20, 25, 25 };
|
||||||
|
CHECK_GPU(GpuRasterD3D11ClipRect(&rect, &clip, 10, 10, &output));
|
||||||
|
CHECK_GPU(output.left == output.right && output.top == output.bottom);
|
||||||
|
rect = { 1.5, 2, 4, 5 };
|
||||||
|
CHECK_GPU(!GpuRasterD3D11ClipRect(&rect, &clip, 10, 10, &output));
|
||||||
|
rect.left = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
CHECK_GPU(!GpuRasterD3D11ClipRect(&rect, &clip, 10, 10, &output));
|
||||||
|
rect.left = std::numeric_limits<double>::infinity();
|
||||||
|
CHECK_GPU(!GpuRasterD3D11ClipRect(&rect, &clip, 10, 10, &output));
|
||||||
|
rect.left = 2147483648.0;
|
||||||
|
CHECK_GPU(!GpuRasterD3D11ClipRect(&rect, &clip, 10, 10, &output));
|
||||||
|
rect = { 6, 2, 4, 5 };
|
||||||
|
CHECK_GPU(!GpuRasterD3D11ClipRect(&rect, &clip, 10, 10, &output));
|
||||||
|
CHECK_GPU(!GpuRasterD3D11ClipRect(nullptr, &clip, 10, 10, &output));
|
||||||
|
CHECK_GPU(!GpuRasterD3D11ClipRect(&rect, &clip, 0, 10, &output));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef GPU_RASTER_STANDALONE
|
||||||
|
struct GpuRasterTestDevice {
|
||||||
|
ID3D11Device* device = nullptr;
|
||||||
|
ID3D11DeviceContext* context = nullptr;
|
||||||
|
ID3D11DeviceContext1* context1 = nullptr;
|
||||||
|
ID3D11Texture2D* texture = nullptr;
|
||||||
|
ID3D11Texture2D* readback = nullptr;
|
||||||
|
ID3D11RenderTargetView* view = nullptr;
|
||||||
|
|
||||||
|
~GpuRasterTestDevice() {
|
||||||
|
if (view) view->Release();
|
||||||
|
if (readback) readback->Release();
|
||||||
|
if (texture) texture->Release();
|
||||||
|
if (context1) context1->Release();
|
||||||
|
if (context) context->Release();
|
||||||
|
if (device) device->Release();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool TestGpuRectanglePixels(DXGI_FORMAT format)
|
||||||
|
{
|
||||||
|
GpuRasterTestDevice gpu;
|
||||||
|
CHECK_GPU(SUCCEEDED(D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_WARP, nullptr,
|
||||||
|
0, nullptr, 0, D3D11_SDK_VERSION,
|
||||||
|
&gpu.device, nullptr, &gpu.context)));
|
||||||
|
CHECK_GPU(SUCCEEDED(gpu.context->QueryInterface(__uuidof(ID3D11DeviceContext1),
|
||||||
|
(void**)&gpu.context1)));
|
||||||
|
D3D11_FEATURE_DATA_D3D11_OPTIONS options = {};
|
||||||
|
CHECK_GPU(SUCCEEDED(gpu.device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS,
|
||||||
|
&options, sizeof(options))));
|
||||||
|
CHECK_GPU(options.ClearView);
|
||||||
|
D3D11_TEXTURE2D_DESC desc = {};
|
||||||
|
desc.Width = desc.Height = 16;
|
||||||
|
desc.MipLevels = desc.ArraySize = desc.SampleDesc.Count = 1;
|
||||||
|
desc.Format = format;
|
||||||
|
desc.BindFlags = D3D11_BIND_RENDER_TARGET;
|
||||||
|
CHECK_GPU(SUCCEEDED(gpu.device->CreateTexture2D(&desc, nullptr, &gpu.texture)));
|
||||||
|
CHECK_GPU(SUCCEEDED(gpu.device->CreateRenderTargetView(gpu.texture, nullptr, &gpu.view)));
|
||||||
|
desc.Usage = D3D11_USAGE_STAGING;
|
||||||
|
desc.BindFlags = 0;
|
||||||
|
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||||
|
CHECK_GPU(SUCCEEDED(gpu.device->CreateTexture2D(&desc, nullptr, &gpu.readback)));
|
||||||
|
|
||||||
|
const float blue[4] = { 0, 0, 1, 1 }, red[4] = { 1, 0, 0, 1 }, clear[4] = { 0, 0, 0, 0 };
|
||||||
|
gpu.context->ClearRenderTargetView(gpu.view, blue);
|
||||||
|
GpuRasterRect rect = { -3, 2, 12, 20 };
|
||||||
|
D3D11_RECT clip = { 3, 4, 10, 11 };
|
||||||
|
// ClearView must use the explicit clip, not the context's scissor state.
|
||||||
|
D3D11_RECT scissor = { 0, 0, 1, 1 };
|
||||||
|
gpu.context->RSSetScissorRects(1, &scissor);
|
||||||
|
gpu.context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||||
|
CHECK_GPU(GpuRasterD3D11FillRect(gpu.context1, gpu.view, 16, 16, &rect, &clip, red));
|
||||||
|
rect = { 5, 5, 7, 7 };
|
||||||
|
clip = { 0, 0, 16, 16 };
|
||||||
|
CHECK_GPU(GpuRasterD3D11FillRect(gpu.context1, gpu.view, 16, 16, &rect, &clip, clear));
|
||||||
|
rect = { 50, 50, 60, 60 };
|
||||||
|
CHECK_GPU(GpuRasterD3D11FillRect(gpu.context1, gpu.view, 16, 16, &rect, &clip, clear));
|
||||||
|
rect = { 0.5, 0, 16, 16 };
|
||||||
|
CHECK_GPU(!GpuRasterD3D11FillRect(gpu.context1, gpu.view, 16, 16, &rect, &clip, clear));
|
||||||
|
CHECK_GPU(!GpuRasterD3D11FillRect(nullptr, gpu.view, 16, 16, &rect, &clip, clear));
|
||||||
|
|
||||||
|
D3D11_PRIMITIVE_TOPOLOGY topology;
|
||||||
|
gpu.context->IAGetPrimitiveTopology(&topology);
|
||||||
|
CHECK_GPU(topology == D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||||
|
UINT count = 1;
|
||||||
|
gpu.context->RSGetScissorRects(&count, &scissor);
|
||||||
|
CHECK_GPU(count == 1 && scissor.left == 0 && scissor.top == 0 &&
|
||||||
|
scissor.right == 1 && scissor.bottom == 1);
|
||||||
|
|
||||||
|
gpu.context->CopyResource(gpu.readback, gpu.texture);
|
||||||
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
|
CHECK_GPU(SUCCEEDED(gpu.context->Map(gpu.readback, 0, D3D11_MAP_READ, 0, &map)));
|
||||||
|
bool equal = true;
|
||||||
|
for (unsigned y = 0; y < 16; ++y) {
|
||||||
|
const uint32_t* row = reinterpret_cast<const uint32_t*>(
|
||||||
|
static_cast<const uint8_t*>(map.pData) + y * map.RowPitch);
|
||||||
|
for (unsigned x = 0; x < 16; ++x) {
|
||||||
|
bool isRed = x >= 3 && x < 10 && y >= 4 && y < 11;
|
||||||
|
uint32_t expected = (isRed == (format == DXGI_FORMAT_R8G8B8A8_UNORM))
|
||||||
|
? 0xff0000ff : 0xffff0000;
|
||||||
|
if (x >= 5 && x < 7 && y >= 5 && y < 7) expected = 0;
|
||||||
|
equal = equal && row[x] == expected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gpu.context->Unmap(gpu.readback, 0);
|
||||||
|
CHECK_GPU(equal);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return TestGpuRectangleClipping() &&
|
||||||
|
TestGpuRectanglePixels(DXGI_FORMAT_R8G8B8A8_UNORM) &&
|
||||||
|
TestGpuRectanglePixels(DXGI_FORMAT_B8G8R8A8_UNORM) ? 0 : 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
TEST(GpuRasterD3D11, ClipRect) { EXPECT_TRUE(TestGpuRectangleClipping()); }
|
||||||
|
// WARP/Context1 is not available on every supported Windows installation.
|
||||||
|
// Run the standalone pixel tests on Windows 8+ with a D3D11.1 runtime.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef CHECK_GPU
|
||||||
|
|
@ -53,6 +53,9 @@ LOCAL_INCLUDES += [
|
||||||
|
|
||||||
FINAL_LIBRARY = 'xul-gtest'
|
FINAL_LIBRARY = 'xul-gtest'
|
||||||
|
|
||||||
|
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows' and CONFIG['MOZ_ENABLE_D3D10_LAYER']:
|
||||||
|
SOURCES += ['TestGpuRasterD3D11.cpp']
|
||||||
|
|
||||||
CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
|
CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
|
||||||
|
|
||||||
if CONFIG['GNU_CXX']:
|
if CONFIG['GNU_CXX']:
|
||||||
|
|
|
||||||
|
|
@ -468,6 +468,7 @@ private:
|
||||||
DECL_GFX_PREF(Once, "layers.componentalpha.enabled", ComponentAlphaEnabled, bool, true);
|
DECL_GFX_PREF(Once, "layers.componentalpha.enabled", ComponentAlphaEnabled, bool, true);
|
||||||
DECL_GFX_PREF(Live, "layers.composer2d.enabled", Composer2DCompositionEnabled, bool, false);
|
DECL_GFX_PREF(Live, "layers.composer2d.enabled", Composer2DCompositionEnabled, bool, false);
|
||||||
DECL_GFX_PREF(Once, "layers.d3d11.force-warp", LayersD3D11ForceWARP, bool, false);
|
DECL_GFX_PREF(Once, "layers.d3d11.force-warp", LayersD3D11ForceWARP, bool, false);
|
||||||
|
DECL_GFX_PREF(Once, "layers.d3d11.gpu-rectangle-fills.enabled", D3D11GpuRectangleFills, bool, false);
|
||||||
DECL_GFX_PREF(Live, "layers.deaa.enabled", LayersDEAAEnabled, bool, false);
|
DECL_GFX_PREF(Live, "layers.deaa.enabled", LayersDEAAEnabled, bool, false);
|
||||||
DECL_GFX_PREF(Live, "layers.draw-bigimage-borders", DrawBigImageBorders, bool, false);
|
DECL_GFX_PREF(Live, "layers.draw-bigimage-borders", DrawBigImageBorders, bool, false);
|
||||||
DECL_GFX_PREF(Live, "layers.draw-borders", DrawLayerBorders, bool, false);
|
DECL_GFX_PREF(Live, "layers.draw-borders", DrawLayerBorders, bool, false);
|
||||||
|
|
|
||||||
|
|
@ -4570,6 +4570,8 @@ pref("gfx.direct2d.force-enabled", false);
|
||||||
|
|
||||||
pref("layers.prefer-opengl", false);
|
pref("layers.prefer-opengl", false);
|
||||||
pref("layers.prefer-d3d9", false);
|
pref("layers.prefer-d3d9", false);
|
||||||
|
// Experimental C GPU rectangle path. Requires D3D11.1 ClearView support and a restart.
|
||||||
|
pref("layers.d3d11.gpu-rectangle-fills.enabled", false);
|
||||||
// Enable fallback if d3d11 can't be used. See bug #1262187
|
// Enable fallback if d3d11 can't be used. See bug #1262187
|
||||||
pref("layers.allow-d3d9-fallback", true);
|
pref("layers.allow-d3d9-fallback", true);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue