Initialize D3D format table.

Set up the expected formats we'll want.
Doesn't include YUV formats just yet.

Bug: skia:9935
Change-Id: I934a7ef006b5a218a5f637774aea5f082202cd3a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/273877
Commit-Queue: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Jim Van Verth 2020-02-28 09:34:07 -05:00 committed by Skia Commit-Bot
parent bde9fcce15
commit 888ba8b3da
3 changed files with 547 additions and 3 deletions

View File

@ -143,7 +143,7 @@ public:
* If the backend API is Direct3D this gets the format as a DXGI_FORMAT and returns true.
* Otherwise, returns false.
*/
bool asDxgiFormat(DXGI_FORMAT*) const;
bool asDxgiFormat(DXGI_FORMAT*) const;
#endif
/**

View File

@ -105,7 +105,8 @@ void GrD3DCaps::init(const GrContextOptions& contextOptions, IDXGIAdapter1* adap
this->initGrCaps(optionsDesc, options2Desc);
this->initShaderCaps(adapterDesc.VendorId, optionsDesc);
// TODO: set up formats and stencil
this->initFormatTable(adapterDesc, device);
// TODO: set up stencil
if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
this->applyDriverCorrectnessWorkarounds(adapterDesc.VendorId);
@ -202,6 +203,490 @@ void GrD3DCaps::applyDriverCorrectnessWorkarounds(int vendorID) {
// Nothing yet.
}
// These are all the valid DXGI_FORMATs that we support in Skia. They are roughly ordered from most
// frequently used to least to improve look up times in arrays.
static constexpr DXGI_FORMAT kDxgiFormats[] = {
DXGI_FORMAT_R8G8B8A8_UNORM,
DXGI_FORMAT_R8_UNORM,
DXGI_FORMAT_B8G8R8A8_UNORM,
DXGI_FORMAT_B5G6R5_UNORM,
DXGI_FORMAT_R16G16B16A16_FLOAT,
DXGI_FORMAT_R16_FLOAT,
DXGI_FORMAT_R8G8_UNORM,
DXGI_FORMAT_R10G10B10A2_UNORM,
DXGI_FORMAT_B4G4R4A4_UNORM,
DXGI_FORMAT_R32G32B32A32_FLOAT,
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
DXGI_FORMAT_BC1_UNORM,
DXGI_FORMAT_R16_UNORM,
DXGI_FORMAT_R16G16_UNORM,
DXGI_FORMAT_R16G16B16A16_UNORM,
DXGI_FORMAT_R16G16_FLOAT
};
void GrD3DCaps::setColorType(GrColorType colorType, std::initializer_list<DXGI_FORMAT> formats) {
#ifdef SK_DEBUG
for (size_t i = 0; i < kNumDxgiFormats; ++i) {
const auto& formatInfo = fFormatTable[i];
for (int j = 0; j < formatInfo.fColorTypeInfoCount; ++j) {
const auto& ctInfo = formatInfo.fColorTypeInfos[j];
if (ctInfo.fColorType == colorType &&
!SkToBool(ctInfo.fFlags & ColorTypeInfo::kWrappedOnly_Flag)) {
bool found = false;
for (auto it = formats.begin(); it != formats.end(); ++it) {
if (kDxgiFormats[i] == *it) {
found = true;
}
}
SkASSERT(found);
}
}
}
#endif
int idx = static_cast<int>(colorType);
for (auto it = formats.begin(); it != formats.end(); ++it) {
const auto& info = this->getFormatInfo(*it);
for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
if (info.fColorTypeInfos[i].fColorType == colorType) {
fColorTypeToFormatTable[idx] = *it;
return;
}
}
}
}
const GrD3DCaps::FormatInfo& GrD3DCaps::getFormatInfo(DXGI_FORMAT format) const {
GrD3DCaps* nonConstThis = const_cast<GrD3DCaps*>(this);
return nonConstThis->getFormatInfo(format);
}
GrD3DCaps::FormatInfo& GrD3DCaps::getFormatInfo(DXGI_FORMAT format) {
static_assert(SK_ARRAY_COUNT(kDxgiFormats) == GrD3DCaps::kNumDxgiFormats,
"Size of DXGI_FORMATs array must match static value in header");
for (size_t i = 0; i < SK_ARRAY_COUNT(kDxgiFormats); ++i) {
if (kDxgiFormats[i] == format) {
return fFormatTable[i];
}
}
static FormatInfo kInvalidFormat;
return kInvalidFormat;
}
void GrD3DCaps::initFormatTable(const DXGI_ADAPTER_DESC& adapterDesc, ID3D12Device* device) {
static_assert(SK_ARRAY_COUNT(kDxgiFormats) == GrD3DCaps::kNumDxgiFormats,
"Size of DXGI_FORMATs array must match static value in header");
std::fill_n(fColorTypeToFormatTable, kGrColorTypeCnt, DXGI_FORMAT_UNKNOWN);
// Go through all the formats and init their support surface and data GrColorTypes.
// Format: DXGI_FORMAT_R8G8B8A8_UNORM
{
constexpr DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM;
auto& info = this->getFormatInfo(format);
info.init(adapterDesc, device, format);
info.fBytesPerPixel = 4;
if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
info.fColorTypeInfoCount = 2;
info.fColorTypeInfos.reset(new ColorTypeInfo[info.fColorTypeInfoCount]());
int ctIdx = 0;
// Format: DXGI_FORMAT_R8G8B8A8_UNORM, Surface: kRGBA_8888
{
constexpr GrColorType ct = GrColorType::kRGBA_8888;
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = ct;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
}
// Format: DXGI_FORMAT_R8G8B8A8_UNORM, Surface: kRGB_888x
{
constexpr GrColorType ct = GrColorType::kRGB_888x;
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = ct;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
ctInfo.fReadSwizzle = GrSwizzle("rgb1");
}
}
}
// Format: DXGI_FORMAT_R8_UNORM
{
constexpr DXGI_FORMAT format = DXGI_FORMAT_R8_UNORM;
auto& info = this->getFormatInfo(format);
info.init(adapterDesc, device, format);
info.fBytesPerPixel = 1;
if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
info.fColorTypeInfoCount = 2;
info.fColorTypeInfos.reset(new ColorTypeInfo[info.fColorTypeInfoCount]());
int ctIdx = 0;
// Format: DXGI_FORMAT_R8_UNORM, Surface: kAlpha_8
{
constexpr GrColorType ct = GrColorType::kAlpha_8;
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = ct;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
ctInfo.fReadSwizzle = GrSwizzle("rrrr");
ctInfo.fOutputSwizzle = GrSwizzle("aaaa");
}
// Format: DXGI_FORMAT_R8_UNORM, Surface: kGray_8
{
constexpr GrColorType ct = GrColorType::kGray_8;
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = ct;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
ctInfo.fReadSwizzle = GrSwizzle("rrr1");
}
}
}
// Format: DXGI_FORMAT_B8G8R8A8_UNORM
{
constexpr DXGI_FORMAT format = DXGI_FORMAT_B8G8R8A8_UNORM;
auto& info = this->getFormatInfo(format);
info.init(adapterDesc, device, format);
info.fBytesPerPixel = 4;
if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos.reset(new ColorTypeInfo[info.fColorTypeInfoCount]());
int ctIdx = 0;
// Format: DXGI_FORMAT_B8G8R8A8_UNORM, Surface: kBGRA_8888
{
constexpr GrColorType ct = GrColorType::kBGRA_8888;
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = ct;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
}
}
}
// Format: DXGI_FORMAT_B5G6R5_UNORM
{
constexpr DXGI_FORMAT format = DXGI_FORMAT_B5G6R5_UNORM;
auto& info = this->getFormatInfo(format);
info.init(adapterDesc, device, format);
info.fBytesPerPixel = 2;
if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos.reset(new ColorTypeInfo[info.fColorTypeInfoCount]());
int ctIdx = 0;
// Format: DXGI_FORMAT_B5G6R5_UNORM, Surface: kBGR_565
{
constexpr GrColorType ct = GrColorType::kBGR_565;
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = ct;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
}
}
}
// Format: DXGI_FORMAT_R16G16B16A16_FLOAT
{
constexpr DXGI_FORMAT format = DXGI_FORMAT_R16G16B16A16_FLOAT;
auto& info = this->getFormatInfo(format);
info.init(adapterDesc, device, format);
info.fBytesPerPixel = 8;
if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
info.fColorTypeInfoCount = 2;
info.fColorTypeInfos.reset(new ColorTypeInfo[info.fColorTypeInfoCount]());
int ctIdx = 0;
// Format: DXGI_FORMAT_R16G16B16A16_FLOAT, Surface: GrColorType::kRGBA_F16
{
constexpr GrColorType ct = GrColorType::kRGBA_F16;
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = ct;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
}
// Format: DXGI_FORMAT_R16G16B16A16_FLOAT, Surface: GrColorType::kRGBA_F16_Clamped
{
constexpr GrColorType ct = GrColorType::kRGBA_F16_Clamped;
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = ct;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
}
}
}
// Format: DXGI_FORMAT_R16_FLOAT
{
constexpr DXGI_FORMAT format = DXGI_FORMAT_R16_FLOAT;
auto& info = this->getFormatInfo(format);
info.init(adapterDesc, device, format);
info.fBytesPerPixel = 2;
if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos.reset(new ColorTypeInfo[info.fColorTypeInfoCount]());
int ctIdx = 0;
// Format: DXGI_FORMAT_R16_FLOAT, Surface: kAlpha_F16
{
constexpr GrColorType ct = GrColorType::kAlpha_F16;
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = ct;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
ctInfo.fReadSwizzle = GrSwizzle("rrrr");
ctInfo.fOutputSwizzle = GrSwizzle("aaaa");
}
}
}
// Format: DXGI_FORMAT_R8G8_UNORM
{
constexpr DXGI_FORMAT format = DXGI_FORMAT_R8G8_UNORM;
auto& info = this->getFormatInfo(format);
info.init(adapterDesc, device, format);
info.fBytesPerPixel = 2;
if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos.reset(new ColorTypeInfo[info.fColorTypeInfoCount]());
int ctIdx = 0;
// Format: DXGI_FORMAT_R8G8_UNORM, Surface: kRG_88
{
constexpr GrColorType ct = GrColorType::kRG_88;
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = ct;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
}
}
}
// Format: DXGI_FORMAT_R10G10B10A2_UNORM
{
constexpr DXGI_FORMAT format = DXGI_FORMAT_R10G10B10A2_UNORM;
auto& info = this->getFormatInfo(format);
info.init(adapterDesc, device, format);
info.fBytesPerPixel = 4;
if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos.reset(new ColorTypeInfo[info.fColorTypeInfoCount]());
int ctIdx = 0;
// Format: DXGI_FORMAT_R10G10B10A2_UNORM, Surface: kRGBA_1010102
{
constexpr GrColorType ct = GrColorType::kRGBA_1010102;
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = ct;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
}
}
}
// Format: DXGI_FORMAT_B4G4R4A4_UNORM
{
constexpr DXGI_FORMAT format = DXGI_FORMAT_B4G4R4A4_UNORM;
auto& info = this->getFormatInfo(format);
info.init(adapterDesc, device, format);
info.fBytesPerPixel = 2;
if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos.reset(new ColorTypeInfo[info.fColorTypeInfoCount]());
int ctIdx = 0;
// Format: DXGI_FORMAT_B4G4R4A4_UNORM, Surface: kABGR_4444
{
constexpr GrColorType ct = GrColorType::kABGR_4444;
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = ct;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
ctInfo.fReadSwizzle = GrSwizzle("bgra");
ctInfo.fOutputSwizzle = GrSwizzle("bgra");
}
}
}
// Format: DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
{
constexpr DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
auto& info = this->getFormatInfo(format);
info.init(adapterDesc, device, format);
info.fBytesPerPixel = 4;
if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos.reset(new ColorTypeInfo[info.fColorTypeInfoCount]());
int ctIdx = 0;
// Format: DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, Surface: kRGBA_8888_SRGB
{
constexpr GrColorType ct = GrColorType::kRGBA_8888_SRGB;
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = ct;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
}
}
}
// Format: DXGI_FORMAT_R16_UNORM
{
constexpr DXGI_FORMAT format = DXGI_FORMAT_R16_UNORM;
auto& info = this->getFormatInfo(format);
info.init(adapterDesc, device, format);
info.fBytesPerPixel = 2;
if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos.reset(new ColorTypeInfo[info.fColorTypeInfoCount]());
int ctIdx = 0;
// Format: DXGI_FORMAT_R16_UNORM, Surface: kAlpha_16
{
constexpr GrColorType ct = GrColorType::kAlpha_16;
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = ct;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
ctInfo.fReadSwizzle = GrSwizzle("rrrr");
ctInfo.fOutputSwizzle = GrSwizzle("aaaa");
}
}
}
// Format: DXGI_FORMAT_R16G16_UNORM
{
constexpr DXGI_FORMAT format = DXGI_FORMAT_R16G16_UNORM;
auto& info = this->getFormatInfo(format);
info.init(adapterDesc, device, format);
info.fBytesPerPixel = 4;
if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos.reset(new ColorTypeInfo[info.fColorTypeInfoCount]());
int ctIdx = 0;
// Format: DXGI_FORMAT_R16G16_UNORM, Surface: kRG_1616
{
constexpr GrColorType ct = GrColorType::kRG_1616;
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = ct;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
}
}
}
// Format: DXGI_FORMAT_R16G16B16A16_UNORM
{
constexpr DXGI_FORMAT format = DXGI_FORMAT_R16G16B16A16_UNORM;
auto& info = this->getFormatInfo(format);
info.init(adapterDesc, device, format);
info.fBytesPerPixel = 8;
if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos.reset(new ColorTypeInfo[info.fColorTypeInfoCount]());
int ctIdx = 0;
// Format: DXGI_FORMAT_R16G16B16A16_UNORM, Surface: kRGBA_16161616
{
constexpr GrColorType ct = GrColorType::kRGBA_16161616;
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = ct;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
}
}
}
// Format: DXGI_FORMAT_R16G16_FLOAT
{
constexpr DXGI_FORMAT format = DXGI_FORMAT_R16G16_FLOAT;
auto& info = this->getFormatInfo(format);
info.init(adapterDesc, device, format);
info.fBytesPerPixel = 4;
if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos.reset(new ColorTypeInfo[info.fColorTypeInfoCount]());
int ctIdx = 0;
// Format: DXGI_FORMAT_R16G16_FLOAT, Surface: kRG_F16
{
constexpr GrColorType ct = GrColorType::kRG_F16;
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = ct;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
}
}
}
// Format: DXGI_FORMAT_BC1_UNORM
{
constexpr DXGI_FORMAT format = DXGI_FORMAT_BC1_UNORM;
auto& info = this->getFormatInfo(format);
info.init(adapterDesc, device, format);
info.fBytesPerPixel = 0;
// No supported GrColorTypes.
}
////////////////////////////////////////////////////////////////////////////
// Map GrColorTypes (used for creating GrSurfaces) to DXGI_FORMATs. The order in which the
// formats are passed into the setColorType function indicates the priority in selecting which
// format we use for a given GrcolorType.
this->setColorType(GrColorType::kAlpha_8, { DXGI_FORMAT_R8_UNORM });
this->setColorType(GrColorType::kBGR_565, { DXGI_FORMAT_B5G6R5_UNORM });
this->setColorType(GrColorType::kABGR_4444, { DXGI_FORMAT_B4G4R4A4_UNORM });
this->setColorType(GrColorType::kRGBA_8888, { DXGI_FORMAT_R8G8B8A8_UNORM });
this->setColorType(GrColorType::kRGBA_8888_SRGB, { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB });
this->setColorType(GrColorType::kRGB_888x, { DXGI_FORMAT_R8G8B8A8_UNORM });
this->setColorType(GrColorType::kRG_88, { DXGI_FORMAT_R8G8_UNORM });
this->setColorType(GrColorType::kBGRA_8888, { DXGI_FORMAT_B8G8R8A8_UNORM });
this->setColorType(GrColorType::kRGBA_1010102, { DXGI_FORMAT_R10G10B10A2_UNORM });
this->setColorType(GrColorType::kGray_8, { DXGI_FORMAT_R8_UNORM });
this->setColorType(GrColorType::kAlpha_F16, { DXGI_FORMAT_R16_FLOAT });
this->setColorType(GrColorType::kRGBA_F16, { DXGI_FORMAT_R16G16B16A16_FLOAT });
this->setColorType(GrColorType::kRGBA_F16_Clamped, { DXGI_FORMAT_R16G16B16A16_FLOAT });
this->setColorType(GrColorType::kAlpha_16, { DXGI_FORMAT_R16_UNORM });
this->setColorType(GrColorType::kRG_1616, { DXGI_FORMAT_R16G16_UNORM });
this->setColorType(GrColorType::kRGBA_16161616, { DXGI_FORMAT_R16G16B16A16_UNORM });
this->setColorType(GrColorType::kRG_F16, { DXGI_FORMAT_R16G16_FLOAT });
}
void GrD3DCaps::FormatInfo::InitFormatFlags(const D3D12_FEATURE_DATA_FORMAT_SUPPORT& formatSupport,
uint16_t* flags) {
if (SkToBool(D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE & formatSupport.Support1)) {
*flags = *flags | kTexturable_Flag;
// Ganesh assumes that all renderable surfaces are also texturable
if (SkToBool(D3D12_FORMAT_SUPPORT1_RENDER_TARGET & formatSupport.Support1) &&
SkToBool(D3D12_FORMAT_SUPPORT1_BLENDABLE & formatSupport.Support1)) {
*flags = *flags | kRenderable_Flag;
}
}
if (SkToBool(D3D12_FORMAT_SUPPORT1_MULTISAMPLE_RENDERTARGET & formatSupport.Support1)) {
*flags = *flags | kMSAA_Flag;
}
if (SkToBool(D3D12_FORMAT_SUPPORT1_MULTISAMPLE_RESOLVE & formatSupport.Support1)) {
*flags = *flags | kResolve_Flag;
}
}
static bool multisample_count_supported(ID3D12Device* device, DXGI_FORMAT format, int sampleCount) {
D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS msqLevels;
msqLevels.Format = format;
msqLevels.SampleCount = sampleCount;
HRESULT hr = device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &msqLevels,
sizeof(msqLevels));
SkASSERT(SUCCEEDED(hr));
return msqLevels.NumQualityLevels > 0;
}
void GrD3DCaps::FormatInfo::initSampleCounts(const DXGI_ADAPTER_DESC& adapterDesc,
ID3D12Device* device, DXGI_FORMAT format) {
if (multisample_count_supported(device, format, 1)) {
fColorSampleCounts.push_back(1);
}
// TODO: test these
//if (kImagination_D3DVendor == adapterDesc.VendorId) {
// // MSAA does not work on imagination
// return;
//}
//if (kIntel_D3DVendor == adapterDesc.VendorId) {
// // MSAA doesn't work well on Intel GPUs chromium:527565, chromium:983926
// return;
//}
if (multisample_count_supported(device, format, 2)) {
fColorSampleCounts.push_back(2);
}
if (multisample_count_supported(device, format, 4)) {
fColorSampleCounts.push_back(4);
}
if (multisample_count_supported(device, format, 8)) {
fColorSampleCounts.push_back(8);
}
if (multisample_count_supported(device, format, 16)) {
fColorSampleCounts.push_back(16);
}
// Standard sample locations are not defined for more than 16 samples, and we don't need more
// than 16. Omit 32 and 64.
}
void GrD3DCaps::FormatInfo::init(const DXGI_ADAPTER_DESC& adapterDesc, ID3D12Device* device,
DXGI_FORMAT format) {
D3D12_FEATURE_DATA_FORMAT_SUPPORT formatSupportDesc;
formatSupportDesc.Format = format;
HRESULT hr = device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &formatSupportDesc,
sizeof(formatSupportDesc));
SkASSERT(SUCCEEDED(hr));
InitFormatFlags(formatSupportDesc, &fFlags);
if (fFlags & kRenderable_Flag) {
this->initSampleCounts(adapterDesc, device, format);
}
}
bool GrD3DCaps::isFormatSRGB(const GrBackendFormat& format) const {
// TODO
return false;

View File

@ -30,7 +30,7 @@ public:
bool isFormatTexturableAndUploadable(GrColorType, const GrBackendFormat&) const override;
bool isFormatTexturable(const GrBackendFormat&) const override;
bool isFormatCopyable(const GrBackendFormat&) const override { return true; }
bool isFormatCopyable(const GrBackendFormat&) const override { return false; }
bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format,
int sampleCount = 1) const override;
@ -84,6 +84,8 @@ private:
const D3D12_FEATURE_DATA_D3D12_OPTIONS2&);
void initShaderCaps(int vendorID, const D3D12_FEATURE_DATA_D3D12_OPTIONS& optionsDesc);
void initFormatTable(const DXGI_ADAPTER_DESC&, ID3D12Device*);
void applyDriverCorrectnessWorkarounds(int vendorID);
bool onSurfaceSupportsWritePixels(const GrSurface*) const override;
@ -96,6 +98,63 @@ private:
SupportedRead onSupportedReadPixelsColorType(GrColorType, const GrBackendFormat&,
GrColorType) const override;
// ColorTypeInfo for a specific format
struct ColorTypeInfo {
GrColorType fColorType = GrColorType::kUnknown;
enum {
kUploadData_Flag = 0x1,
// Does Ganesh itself support rendering to this colorType & format pair. Renderability
// still additionally depends on if the format itself is renderable.
kRenderable_Flag = 0x2,
// Indicates that this colorType is supported only if we are wrapping a texture with
// the given format and colorType. We do not allow creation with this pair.
kWrappedOnly_Flag = 0x4,
};
uint32_t fFlags = 0;
GrSwizzle fReadSwizzle;
GrSwizzle fOutputSwizzle;
};
struct FormatInfo {
uint32_t colorTypeFlags(GrColorType colorType) const {
for (int i = 0; i < fColorTypeInfoCount; ++i) {
if (fColorTypeInfos[i].fColorType == colorType) {
return fColorTypeInfos[i].fFlags;
}
}
return 0;
}
void init(const DXGI_ADAPTER_DESC&, ID3D12Device*, DXGI_FORMAT);
static void InitFormatFlags(const D3D12_FEATURE_DATA_FORMAT_SUPPORT&, uint16_t* flags);
void initSampleCounts(const DXGI_ADAPTER_DESC& adapterDesc, ID3D12Device*, DXGI_FORMAT);
enum {
kTexturable_Flag = 0x1, // Can be sampled in a shader
kRenderable_Flag = 0x2, // Rendertarget and blendable
kMSAA_Flag = 0x4,
kResolve_Flag = 0x8,
};
uint16_t fFlags = 0;
SkTDArray<int> fColorSampleCounts;
// This value is only valid for regular formats. Compressed formats will be 0.
size_t fBytesPerPixel = 0;
std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos;
int fColorTypeInfoCount = 0;
};
static const size_t kNumDxgiFormats = 16;
FormatInfo fFormatTable[kNumDxgiFormats];
FormatInfo& getFormatInfo(DXGI_FORMAT);
const FormatInfo& getFormatInfo(DXGI_FORMAT) const;
DXGI_FORMAT fColorTypeToFormatTable[kGrColorTypeCnt];
void setColorType(GrColorType, std::initializer_list<DXGI_FORMAT> formats);
int fMaxPerStageShaderResourceViews;
int fMaxPerStageUnorderedAccessViews;