Commit 4caa0de5 authored by Louis-Francis Ratté-Boulianne's avatar Louis-Francis Ratté-Boulianne Committed by Erik Faye-Lund
Browse files

d3d12: Refactor support for legacy ARB formats

This change also allows the driver to use red-only formats to emulate
intensity/luminance formats instead of a RGBA format. However, it
isn't possible when alpha is present as it breaks alpha blending.
parent 33a95095
......@@ -797,57 +797,20 @@ d3d12_create_sampler_view(struct pipe_context *pctx,
sampler_view->mip_levels = state->u.tex.last_level - state->u.tex.first_level + 1;
sampler_view->array_size = texture->array_size;
int plane_slice = 0;
const struct util_format_description
*format_desc = util_format_description(state->format);
if (util_format_has_depth(format_desc)) {
enum pipe_swizzle swz[PIPE_SWIZZLE_MAX] = {
PIPE_SWIZZLE_X,
PIPE_SWIZZLE_X,
PIPE_SWIZZLE_X,
PIPE_SWIZZLE_X,
PIPE_SWIZZLE_0,
PIPE_SWIZZLE_1,
PIPE_SWIZZLE_NONE,
};
sampler_view->swizzle_override_r = swz[sampler_view->base.swizzle_r];
sampler_view->swizzle_override_g = swz[sampler_view->base.swizzle_g];
sampler_view->swizzle_override_b = swz[sampler_view->base.swizzle_b];
sampler_view->swizzle_override_a = swz[sampler_view->base.swizzle_a];
} else if (util_format_has_stencil(format_desc)) {
/* When reading from a stencil texture we have to use plane 1, and
* the formats X24S8 and X32_S8X24 have the actual data in the y-channel
* but the shader will read the x component so we need to adjust the swizzle. */
plane_slice = 1;
enum pipe_swizzle swz[PIPE_SWIZZLE_MAX] = {
PIPE_SWIZZLE_Y,
PIPE_SWIZZLE_Y,
PIPE_SWIZZLE_Y,
PIPE_SWIZZLE_Y,
PIPE_SWIZZLE_0,
PIPE_SWIZZLE_1,
PIPE_SWIZZLE_NONE,
};
sampler_view->swizzle_override_r = swz[sampler_view->base.swizzle_r];
sampler_view->swizzle_override_g = swz[sampler_view->base.swizzle_g];
sampler_view->swizzle_override_b = swz[sampler_view->base.swizzle_b];
sampler_view->swizzle_override_a = swz[sampler_view->base.swizzle_a];
} else {
sampler_view->swizzle_override_r = sampler_view->base.swizzle_r;
sampler_view->swizzle_override_g = sampler_view->base.swizzle_g;
sampler_view->swizzle_override_b = sampler_view->base.swizzle_b;
sampler_view->swizzle_override_a = sampler_view->base.swizzle_a;
}
D3D12_SHADER_RESOURCE_VIEW_DESC desc = {};
struct d3d12_format_info format_info = d3d12_get_format_info(state->format, state->target);
pipe_swizzle swizzle[4] = {
(pipe_swizzle) sampler_view->swizzle_override_r,
(pipe_swizzle) sampler_view->swizzle_override_g,
(pipe_swizzle) sampler_view->swizzle_override_b,
(pipe_swizzle) sampler_view->swizzle_override_a
format_info.swizzle[sampler_view->base.swizzle_r],
format_info.swizzle[sampler_view->base.swizzle_g],
format_info.swizzle[sampler_view->base.swizzle_b],
format_info.swizzle[sampler_view->base.swizzle_a]
};
sampler_view->swizzle_override_r = swizzle[0];
sampler_view->swizzle_override_g = swizzle[1];
sampler_view->swizzle_override_b = swizzle[2];
sampler_view->swizzle_override_a = swizzle[3];
desc.Format = d3d12_get_resource_srv_format(state->format);
desc.ViewDimension = view_dimension(state->target, texture->nr_samples);
......@@ -860,22 +823,6 @@ d3d12_create_sampler_view(struct pipe_context *pctx,
desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
}
if (desc.Format == DXGI_FORMAT_UNKNOWN) {
/* The format is not directly supported, but if it is an legacy format, then
* we may be able to emulate it */
auto format_descr = d3d12_get_emulated_view_format(state->format);
if (!format_descr->dxgi_format) {
if (d3d12_debug & D3D12_DEBUG_VERBOSE)
debug_printf("Format %s has no DXGI format and can't be emulated\n",
util_format_name(state->format));
FREE(sampler_view);
return nullptr;
}
desc.Format = format_descr->dxgi_format;
memcpy(swizzle, format_descr->swizzle, sizeof(swizzle));
}
desc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
component_mapping(swizzle[0], D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0),
component_mapping(swizzle[1], D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1),
......@@ -908,7 +855,7 @@ d3d12_create_sampler_view(struct pipe_context *pctx,
desc.Texture2D.MostDetailedMip = state->u.tex.first_level;
desc.Texture2D.MipLevels = sampler_view->mip_levels;
desc.Texture2D.PlaneSlice = plane_slice;
desc.Texture2D.PlaneSlice = format_info.plane_slice;
desc.Texture2D.ResourceMinLODClamp = 0.0f;
break;
case D3D12_SRV_DIMENSION_TEXTURE2DMS:
......@@ -921,7 +868,7 @@ d3d12_create_sampler_view(struct pipe_context *pctx,
desc.Texture2DArray.MipLevels = sampler_view->mip_levels;
desc.Texture2DArray.ResourceMinLODClamp = 0.0f;
desc.Texture2DArray.FirstArraySlice = state->u.tex.first_layer;
desc.Texture2DArray.PlaneSlice = plane_slice;
desc.Texture2DArray.PlaneSlice = format_info.plane_slice;
desc.Texture2DArray.ArraySize = array_size;
break;
case D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY:
......
......@@ -42,6 +42,14 @@ static const DXGI_FORMAT formats[PIPE_FORMAT_COUNT] = {
#define MAP_FORMAT_FLOAT(FMT) \
[PIPE_FORMAT_ ## FMT ## _FLOAT] = DXGI_FORMAT_ ## FMT ## _FLOAT,
#define MAP_EMU_FORMAT(BITS, TYPE) \
[PIPE_FORMAT_L ## BITS ## _ ## TYPE] = DXGI_FORMAT_R ## BITS ## _ ## TYPE, \
[PIPE_FORMAT_I ## BITS ## _ ## TYPE] = DXGI_FORMAT_R ## BITS ## _ ## TYPE, \
[PIPE_FORMAT_L ## BITS ## A ## BITS ## _ ## TYPE] = \
DXGI_FORMAT_R ## BITS ## G ## BITS ## _ ## TYPE,
[PIPE_FORMAT_A ## BITS ## _ ## TYPE] = DXGI_FORMAT_R ## BITS ## _ ## TYPE, \
MAP_EMU_FORMAT_NO_ALPHA(BITS, TYPE)
MAP_FORMAT_NORM(R8)
MAP_FORMAT_INT(R8)
......@@ -78,6 +86,20 @@ static const DXGI_FORMAT formats[PIPE_FORMAT_COUNT] = {
MAP_FORMAT_INT(R16G16B16A16)
MAP_FORMAT_FLOAT(R16G16B16A16)
MAP_EMU_FORMAT(8, UNORM)
MAP_EMU_FORMAT(8, SNORM)
MAP_EMU_FORMAT(8, SNORM)
MAP_EMU_FORMAT(8, SINT)
MAP_EMU_FORMAT(8, UINT)
MAP_EMU_FORMAT(16, UNORM)
MAP_EMU_FORMAT(16, SNORM)
MAP_EMU_FORMAT(16, SINT)
MAP_EMU_FORMAT(16, UINT)
MAP_EMU_FORMAT(16, FLOAT)
MAP_EMU_FORMAT(32, SINT)
MAP_EMU_FORMAT(32, UINT)
MAP_EMU_FORMAT(32, FLOAT)
[PIPE_FORMAT_R9G9B9E5_FLOAT] = DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
[PIPE_FORMAT_R11G11B10_FLOAT] = DXGI_FORMAT_R11G11B10_FLOAT,
[PIPE_FORMAT_R10G10B10A2_UINT] = DXGI_FORMAT_R10G10B10A2_UINT,
......@@ -147,35 +169,51 @@ d3d12_get_resource_srv_format(enum pipe_format f)
}
}
#define EMU_ALPHA_SWIZZLE { PIPE_SWIZZLE_0, PIPE_SWIZZLE_0, PIPE_SWIZZLE_0, PIPE_SWIZZLE_X }
#define EMU_LUMINANCE_SWIZZLE { PIPE_SWIZZLE_X, PIPE_SWIZZLE_X, PIPE_SWIZZLE_X, PIPE_SWIZZLE_1 }
#define EMU_LUMINANCE_ALPHA_SWIZZLE { PIPE_SWIZZLE_X, PIPE_SWIZZLE_X, PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y }
#define EMU_INTENSITY_SWIZZLE { PIPE_SWIZZLE_X, PIPE_SWIZZLE_X, PIPE_SWIZZLE_X, PIPE_SWIZZLE_X }
#define EMU_FORMAT(BITS, TYPE) \
[PIPE_FORMAT_A ## BITS ## _ ## TYPE] = {DXGI_FORMAT_R ## BITS ## _ ## TYPE, EMU_ALPHA_SWIZZLE}, \
[PIPE_FORMAT_L ## BITS ## _ ## TYPE] = {DXGI_FORMAT_R ## BITS ## _ ## TYPE, EMU_LUMINANCE_SWIZZLE}, \
[PIPE_FORMAT_I ## BITS ## _ ## TYPE] = {DXGI_FORMAT_R ## BITS ## _ ## TYPE, EMU_INTENSITY_SWIZZLE}, \
[PIPE_FORMAT_L ## BITS ## A ## BITS ## _ ## TYPE] = \
{DXGI_FORMAT_R ## BITS ## G ## BITS ## _ ## TYPE, EMU_LUMINANCE_ALPHA_SWIZZLE}
const struct d3d12_arb_emulation_format arb_emulation_format[PIPE_FORMAT_COUNT] = {
EMU_FORMAT(8, UNORM),
EMU_FORMAT(8, SINT),
EMU_FORMAT(8, UINT),
EMU_FORMAT(16, UNORM),
EMU_FORMAT(16, SINT),
EMU_FORMAT(16, UINT),
EMU_FORMAT(16, FLOAT),
EMU_FORMAT(32, SINT),
EMU_FORMAT(32, UINT),
EMU_FORMAT(32, FLOAT)
};
#define DEF_SWIZZLE(name, X, Y, Z, W) \
static const enum pipe_swizzle name ## _SWIZZLE[PIPE_SWIZZLE_MAX] = \
{ PIPE_SWIZZLE_ ## X, PIPE_SWIZZLE_ ## Y, PIPE_SWIZZLE_ ## Z, PIPE_SWIZZLE_ ## W, \
PIPE_SWIZZLE_0, PIPE_SWIZZLE_1, PIPE_SWIZZLE_NONE }
const struct d3d12_arb_emulation_format *
d3d12_get_emulated_view_format(enum pipe_format format)
struct d3d12_format_info
d3d12_get_format_info(enum pipe_format pformat, enum pipe_texture_target target)
{
return &arb_emulation_format[format];
DEF_SWIZZLE(IDENTITY, X, Y, Z, W);
DEF_SWIZZLE(ALPHA, 0, 0, 0, W);
DEF_SWIZZLE(BUFFER, 0, 0, 0, X);
DEF_SWIZZLE(INTENSITY, X, X, X, X);
DEF_SWIZZLE(LUMINANCE, X, X, X, 1);
DEF_SWIZZLE(LUMINANCE_ALPHA, X, X, X, Y);
DEF_SWIZZLE(DEPTH, X, X, X, X);
DEF_SWIZZLE(STENCIL, Y, Y, Y, Y);
const enum pipe_swizzle *swizzle = IDENTITY_SWIZZLE;
unsigned plane_slice = 0;
const struct util_format_description
*format_desc = util_format_description(pformat);
if (!util_format_is_srgb(pformat)) {
if (target == PIPE_BUFFER && util_format_is_alpha(pformat)) {
swizzle = BUFFER_SWIZZLE;
} else if (util_format_is_intensity(pformat)) {
swizzle = INTENSITY_SWIZZLE;
} else if (util_format_is_luminance(pformat)) {
swizzle = LUMINANCE_SWIZZLE;
} else if (util_format_is_luminance_alpha(pformat)) {
swizzle = LUMINANCE_ALPHA_SWIZZLE;
} else if (util_format_is_alpha(pformat)) {
swizzle = ALPHA_SWIZZLE;
} else if (util_format_has_depth(format_desc)) {
swizzle = DEPTH_SWIZZLE;
} else if (util_format_has_stencil(format_desc)) {
/* When reading from a stencil texture we have to use plane 1, and
* the formats X24S8 and X32_S8X24 have the actual data in the y-channel
* but the shader will read the x component so we need to adjust the swizzle. */
plane_slice = 1;
swizzle = STENCIL_SWIZZLE;
}
}
return (struct d3d12_format_info) { .swizzle = swizzle, .plane_slice = plane_slice };
}
enum pipe_format
......
......@@ -45,13 +45,13 @@ d3d12_get_resource_rt_format(enum pipe_format f);
unsigned
d3d12_non_opaque_plane_count(DXGI_FORMAT f);
struct d3d12_arb_emulation_format {
DXGI_FORMAT dxgi_format;
enum pipe_swizzle swizzle[4];
struct d3d12_format_info {
const enum pipe_swizzle *swizzle;
int plane_slice;
};
const struct d3d12_arb_emulation_format *
d3d12_get_emulated_view_format(enum pipe_format format);
struct d3d12_format_info
d3d12_get_format_info(enum pipe_format format, enum pipe_texture_target);
enum pipe_format
d3d12_emulated_vtx_format(enum pipe_format fmt);
......
......@@ -141,9 +141,6 @@ init_texture(struct d3d12_screen *screen,
res->mip_levels = templ->last_level + 1;
res->dxgi_format = d3d12_get_format(templ->format);
if (res->dxgi_format == DXGI_FORMAT_UNKNOWN)
res->dxgi_format = d3d12_get_emulated_view_format(templ->format)->dxgi_format;
D3D12_RESOURCE_DESC desc;
desc.Format = res->dxgi_format;
desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
......
......@@ -499,6 +499,13 @@ d3d12_is_format_supported(struct pipe_screen *pscreen,
return false;
}
/* Don't advertise alpha/luminance_alpha formats because they can't be used
* for render targets and can't be emulated by R/RG formats. Let the state
* tracker choose an RGBA format instead. */
if (util_format_is_alpha(format) ||
util_format_is_luminance_alpha(format))
return false;
DXGI_FORMAT dxgi_format = d3d12_get_format(format);
if (dxgi_format == DXGI_FORMAT_UNKNOWN)
return false;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment