[D3D12] Take 0 being bottom-right sample with 2x MSAA in D3D12 into account
This commit is contained in:
@@ -3081,10 +3081,11 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
|
||||
uint32_t source_tile_pixel_x_reg = 0;
|
||||
uint32_t source_tile_pixel_y_reg = 0;
|
||||
|
||||
// First sample bit at 4x - horizontal sample.
|
||||
// Second sample bit at 4x - vertical sample.
|
||||
// At 2x, the vertical sample is either the first or the second bit
|
||||
// depending on whether 2x is emulated as 4x.
|
||||
// First sample bit at 4x in Direct3D 10.1+ - horizontal sample.
|
||||
// Second sample bit at 4x in Direct3D 10.1+ - vertical sample.
|
||||
// At 2x:
|
||||
// - Native 2x: top is 1 in Direct3D 10.1+, bottom is 0.
|
||||
// - 2x as 4x: top is 0, bottom is 3.
|
||||
|
||||
if (!source_is_64bpp && dest_is_64bpp) {
|
||||
// 32bpp -> 64bpp, need two samples of the source.
|
||||
@@ -3113,14 +3114,15 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
|
||||
// D p0,0 s1 = S p0,0 s0,1 | S p0,0 s1,1
|
||||
// D p1,0 s0 = S p1,0 s0,0 | S p1,0 s1,0
|
||||
// D p1,0 s1 = S p1,0 s0,1 | S p1,0 s1,1
|
||||
// Pixel index can be reused. Sample 0 should become samples 01,
|
||||
// sample 1 or 3 should become samples 23.
|
||||
// Pixel index can be reused. Sample 1 (for native 2x) or 0 (for 2x as
|
||||
// 4x) should become samples 01, sample 0 or 3 should become samples 23.
|
||||
source_sample = dxbc::Src::R(1, dxbc::Src::kZZZZ);
|
||||
if (msaa_2x_supported_) {
|
||||
a.OpIShL(dxbc::Dest::R(1, 0b0100), dest_sample, dxbc::Src::LU(1));
|
||||
a.OpXOr(dxbc::Dest::R(1, 0b0100), dest_sample, dxbc::Src::LU(1));
|
||||
a.OpIShL(dxbc::Dest::R(1, 0b0100), source_sample, dxbc::Src::LU(1));
|
||||
} else {
|
||||
a.OpAnd(dxbc::Dest::R(1, 0b0100), dest_sample, dxbc::Src::LU(0b10));
|
||||
}
|
||||
source_sample = dxbc::Src::R(1, dxbc::Src::kZZZZ);
|
||||
} else {
|
||||
// 32bpp -> 64bpp, 4x -> 1x.
|
||||
// 1 destination horizontal pixel = 2 source horizontal samples.
|
||||
@@ -3201,11 +3203,14 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
|
||||
source_sample = dxbc::Src::R(1, dxbc::Src::kZZZZ);
|
||||
if (key.dest_msaa_samples == xenos::MsaaSamples::k2X) {
|
||||
// 64bpp -> 32bpp, 4x -> 2x.
|
||||
// Destination vertical samples (first or second bit, depending on
|
||||
// support) = source vertical samples (second bit).
|
||||
// Destination vertical samples (1/0 in the first bit for native 2x or
|
||||
// 0/1 in the second bit for 2x as 4x) = source vertical samples
|
||||
// (second bit).
|
||||
if (msaa_2x_supported_) {
|
||||
a.OpBFI(dxbc::Dest::R(1, 0b0100), dxbc::Src::LU(1),
|
||||
dxbc::Src::LU(1), dest_sample, source_sample);
|
||||
a.OpXOr(dxbc::Dest::R(1, 0b0100), source_sample,
|
||||
dxbc::Src::LU(1 << 1));
|
||||
} else {
|
||||
a.OpBFI(dxbc::Dest::R(1, 0b0100), dxbc::Src::LU(1),
|
||||
dxbc::Src::LU(0), source_sample, dest_sample);
|
||||
@@ -3244,18 +3249,21 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
|
||||
// Same BPP, 4x -> 1x/2x.
|
||||
if (key.dest_msaa_samples == xenos::MsaaSamples::k2X) {
|
||||
// Same BPP, 4x -> 2x.
|
||||
// Horizontal pixels to samples. Vertical sample (first or second bit,
|
||||
// depending on support) to second sample bit.
|
||||
// Horizontal pixels to samples. Vertical sample (1/0 in the first bit
|
||||
// for native 2x or 0/1 in the second bit for 2x as 4x) to second
|
||||
// sample bit.
|
||||
source_sample = dxbc::Src::R(1, dxbc::Src::kZZZZ);
|
||||
if (msaa_2x_supported_) {
|
||||
a.OpBFI(dxbc::Dest::R(1, 0b0100), dxbc::Src::LU(31),
|
||||
dxbc::Src::LU(1), dest_sample,
|
||||
dxbc::Src::R(0, dxbc::Src::kXXXX));
|
||||
a.OpXOr(dxbc::Dest::R(1, 0b0100), source_sample,
|
||||
dxbc::Src::LU(1 << 1));
|
||||
} else {
|
||||
a.OpBFI(dxbc::Dest::R(1, 0b0100), dxbc::Src::LU(1),
|
||||
dxbc::Src::LU(0), dxbc::Src::R(0, dxbc::Src::kXXXX),
|
||||
dest_sample);
|
||||
}
|
||||
source_sample = dxbc::Src::R(1, dxbc::Src::kZZZZ);
|
||||
a.OpUShR(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(0, dxbc::Src::kXXXX),
|
||||
dxbc::Src::LU(1));
|
||||
source_tile_pixel_x_reg = 1;
|
||||
@@ -3292,10 +3300,12 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
|
||||
if (key.source_msaa_samples == xenos::MsaaSamples::k2X) {
|
||||
// 2x -> 4x.
|
||||
// Vertical samples (second bit) of 4x destination to vertical sample
|
||||
// (01 or 03, depending on support) of 2x source.
|
||||
// (1, 0 for native 2x, or 0, 3 for 2x as 4x) of 2x source.
|
||||
a.OpUShR(dxbc::Dest::R(1, 0b0100), dest_sample, dxbc::Src::LU(1));
|
||||
source_sample = dxbc::Src::R(1, dxbc::Src::kZZZZ);
|
||||
if (!msaa_2x_supported_) {
|
||||
if (msaa_2x_supported_) {
|
||||
a.OpXOr(dxbc::Dest::R(1, 0b0100), source_sample, dxbc::Src::LU(1));
|
||||
} else {
|
||||
a.OpBFI(dxbc::Dest::R(1, 0b0100), dxbc::Src::LU(1), dxbc::Src::LU(1),
|
||||
source_sample, source_sample);
|
||||
}
|
||||
@@ -3312,12 +3322,14 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
|
||||
// 1x/2x -> different 1x/2x.
|
||||
if (key.source_msaa_samples == xenos::MsaaSamples::k2X) {
|
||||
// 2x -> 1x.
|
||||
// Vertical pixels of 2x destination to vertical samples (01 or 03,
|
||||
// depending on support) of 1x source.
|
||||
// Vertical pixels of 2x destination to vertical samples (1, 0 for
|
||||
// native 2x, or 0, 3 for 2x as 4x) of 1x source.
|
||||
a.OpAnd(dxbc::Dest::R(1, 0b0100), dxbc::Src::R(0, dxbc::Src::kYYYY),
|
||||
dxbc::Src::LU(1));
|
||||
source_sample = dxbc::Src::R(1, dxbc::Src::kZZZZ);
|
||||
if (!msaa_2x_supported_) {
|
||||
if (msaa_2x_supported_) {
|
||||
a.OpXOr(dxbc::Dest::R(1, 0b0100), source_sample, dxbc::Src::LU(1));
|
||||
} else {
|
||||
a.OpBFI(dxbc::Dest::R(1, 0b0100), dxbc::Src::LU(1), dxbc::Src::LU(1),
|
||||
source_sample, source_sample);
|
||||
}
|
||||
@@ -3326,15 +3338,20 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
|
||||
source_tile_pixel_y_reg = 1;
|
||||
} else {
|
||||
// 1x -> 2x.
|
||||
// Vertical samples (first or second bit, depending on support) of 2x
|
||||
// destination to vertical pixels of 1x source.
|
||||
if (!msaa_2x_supported_) {
|
||||
// Vertical samples (1/0 in the first bit for native 2x or 0/1 in the
|
||||
// second bit for 2x as 4x) of 2x destination to vertical pixels of 1x
|
||||
// source.
|
||||
if (msaa_2x_supported_) {
|
||||
a.OpBFI(dxbc::Dest::R(1, 0b0010), dxbc::Src::LU(31), dxbc::Src::LU(1),
|
||||
dxbc::Src::R(0, dxbc::Src::kYYYY), dest_sample);
|
||||
a.OpXOr(dxbc::Dest::R(1, 0b0010), dxbc::Src::R(1, dxbc::Src::kYYYY),
|
||||
dxbc::Src::LU(1));
|
||||
} else {
|
||||
a.OpUShR(dxbc::Dest::R(1, 0b0010), dest_sample, dxbc::Src::LU(1));
|
||||
a.OpBFI(dxbc::Dest::R(1, 0b0010), dxbc::Src::LU(31), dxbc::Src::LU(1),
|
||||
dxbc::Src::R(0, dxbc::Src::kYYYY),
|
||||
dxbc::Src::R(1, dxbc::Src::kYYYY));
|
||||
}
|
||||
a.OpBFI(dxbc::Dest::R(1, 0b0010), dxbc::Src::LU(31), dxbc::Src::LU(1),
|
||||
dxbc::Src::R(0, dxbc::Src::kYYYY),
|
||||
msaa_2x_supported_ ? dest_sample
|
||||
: dxbc::Src::R(1, dxbc::Src::kYYYY));
|
||||
source_tile_pixel_y_reg = 1;
|
||||
}
|
||||
}
|
||||
@@ -3935,13 +3952,15 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
|
||||
dxbc::Src::LU(1), dxbc::Src::R(0, dxbc::Src::kXXXX),
|
||||
dest_sample);
|
||||
}
|
||||
// Vertical sample index in bit 0 for true 2x or in bit 1 for
|
||||
// 4x or for 2x emulated as 4x.
|
||||
// Vertical sample index as 1 or 0 in bit 0 for true 2x or as 0
|
||||
// or 1 in bit 1 for 4x or for 2x emulated as 4x.
|
||||
if (key.dest_msaa_samples == xenos::MsaaSamples::k2X &&
|
||||
msaa_2x_supported_) {
|
||||
a.OpBFI(dxbc::Dest::R(0, 0b0010), dxbc::Src::LU(31),
|
||||
dxbc::Src::LU(1), dxbc::Src::R(0, dxbc::Src::kYYYY),
|
||||
dest_sample);
|
||||
a.OpXOr(dxbc::Dest::R(0, 0b0010),
|
||||
dxbc::Src::R(0, dxbc::Src::kYYYY), dxbc::Src::LU(1));
|
||||
} else {
|
||||
// Using r0.w as a temporary.
|
||||
a.OpUShR(dxbc::Dest::R(0, 0b1000), dest_sample,
|
||||
@@ -3993,19 +4012,22 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
|
||||
// 4x -> 1x/2x.
|
||||
if (key.dest_msaa_samples == xenos::MsaaSamples::k2X) {
|
||||
// 4x -> 2x.
|
||||
// Horizontal pixels to samples. Vertical sample (first or
|
||||
// second bit, depending on support) to second sample bit.
|
||||
// Horizontal pixels to samples. Vertical sample (1, 0 in
|
||||
// the first bit for native 2x or 0, 1 in the second bit for
|
||||
// 2x as 4x) to second sample bit.
|
||||
host_depth_source_sample =
|
||||
dxbc::Src::R(0, dxbc::Src::kWWWW);
|
||||
if (msaa_2x_supported_) {
|
||||
a.OpBFI(dxbc::Dest::R(0, 0b1000), dxbc::Src::LU(31),
|
||||
dxbc::Src::LU(1), dest_sample,
|
||||
dxbc::Src::R(0, dxbc::Src::kXXXX));
|
||||
a.OpXOr(dxbc::Dest::R(0, 0b1000),
|
||||
host_depth_source_sample, dxbc::Src::LU(1 << 1));
|
||||
} else {
|
||||
a.OpBFI(dxbc::Dest::R(0, 0b1000), dxbc::Src::LU(1),
|
||||
dxbc::Src::LU(0),
|
||||
dxbc::Src::R(0, dxbc::Src::kXXXX), dest_sample);
|
||||
}
|
||||
host_depth_source_sample =
|
||||
dxbc::Src::R(0, dxbc::Src::kWWWW);
|
||||
a.OpUShR(dxbc::Dest::R(0, 0b0001),
|
||||
dxbc::Src::R(0, dxbc::Src::kXXXX),
|
||||
dxbc::Src::LU(1));
|
||||
@@ -4042,13 +4064,16 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
|
||||
xenos::MsaaSamples::k2X) {
|
||||
// 2x -> 4x.
|
||||
// Vertical samples (second bit) of 4x destination to
|
||||
// vertical sample (01 or 03, depending on support) of 2x
|
||||
// source.
|
||||
// vertical sample (1, 0 for native 2x, or 0, 3 for 2x as
|
||||
// 4x) of 2x source.
|
||||
a.OpUShR(dxbc::Dest::R(0, 0b1000), dest_sample,
|
||||
dxbc::Src::LU(1));
|
||||
host_depth_source_sample =
|
||||
dxbc::Src::R(0, dxbc::Src::kWWWW);
|
||||
if (!msaa_2x_supported_) {
|
||||
if (msaa_2x_supported_) {
|
||||
a.OpXOr(dxbc::Dest::R(0, 0b1000),
|
||||
host_depth_source_sample, dxbc::Src::LU(1));
|
||||
} else {
|
||||
a.OpBFI(dxbc::Dest::R(0, 0b1000), dxbc::Src::LU(1),
|
||||
dxbc::Src::LU(1), host_depth_source_sample,
|
||||
host_depth_source_sample);
|
||||
@@ -4070,13 +4095,17 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
|
||||
xenos::MsaaSamples::k2X) {
|
||||
// 2x -> 1x.
|
||||
// Vertical pixels of 2x destination to vertical samples
|
||||
// (01 or 03, depending on support) of 1x source.
|
||||
// (1, 0 for native 2x, or 0, 3 for 2x as 4x) of 1x
|
||||
// source.
|
||||
a.OpAnd(dxbc::Dest::R(0, 0b1000),
|
||||
dxbc::Src::R(0, dxbc::Src::kYYYY),
|
||||
dxbc::Src::LU(1));
|
||||
host_depth_source_sample =
|
||||
dxbc::Src::R(0, dxbc::Src::kWWWW);
|
||||
if (!msaa_2x_supported_) {
|
||||
if (msaa_2x_supported_) {
|
||||
a.OpXOr(dxbc::Dest::R(0, 0b1000),
|
||||
host_depth_source_sample, dxbc::Src::LU(1));
|
||||
} else {
|
||||
a.OpBFI(dxbc::Dest::R(0, 0b1000), dxbc::Src::LU(1),
|
||||
dxbc::Src::LU(1), host_depth_source_sample,
|
||||
host_depth_source_sample);
|
||||
@@ -4086,21 +4115,26 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
|
||||
dxbc::Src::LU(1));
|
||||
} else {
|
||||
// 1x -> 2x.
|
||||
// Vertical samples (first or second bit, depending on
|
||||
// support) of 2x destination to vertical pixels of 1x
|
||||
// source.
|
||||
// Vertical samples (1, 0 in the first bit for native 2x
|
||||
// or 0, 1 in the second bit for 2x as 4x) of 2x
|
||||
// destination to vertical pixels of 1x source.
|
||||
// Using r0.w (not needed without source MSAA) as a
|
||||
// temporary.
|
||||
if (!msaa_2x_supported_) {
|
||||
if (msaa_2x_supported_) {
|
||||
a.OpBFI(dxbc::Dest::R(0, 0b0010), dxbc::Src::LU(31),
|
||||
dxbc::Src::LU(1),
|
||||
dxbc::Src::R(0, dxbc::Src::kYYYY), dest_sample);
|
||||
a.OpXOr(dxbc::Dest::R(0, 0b0010),
|
||||
dxbc::Src::R(0, dxbc::Src::kYYYY),
|
||||
dxbc::Src::LU(1));
|
||||
} else {
|
||||
a.OpUShR(dxbc::Dest::R(0, 0b1000), dest_sample,
|
||||
dxbc::Src::LU(1));
|
||||
a.OpBFI(dxbc::Dest::R(0, 0b0010), dxbc::Src::LU(31),
|
||||
dxbc::Src::LU(1),
|
||||
dxbc::Src::R(0, dxbc::Src::kYYYY),
|
||||
dxbc::Src::R(0, dxbc::Src::kWWWW));
|
||||
}
|
||||
a.OpBFI(dxbc::Dest::R(0, 0b0010), dxbc::Src::LU(31),
|
||||
dxbc::Src::LU(1),
|
||||
dxbc::Src::R(0, dxbc::Src::kYYYY),
|
||||
msaa_2x_supported_
|
||||
? dest_sample
|
||||
: dxbc::Src::R(0, dxbc::Src::kWWWW));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6038,7 +6072,7 @@ ID3D12PipelineState* D3D12RenderTargetCache::GetOrCreateDumpPipeline(
|
||||
dxbc::Src::LU(xenos::kEdramTileWidthSamples >>
|
||||
uint32_t(format_is_64bpp)),
|
||||
dxbc::Src::VThreadIDInGroup(dxbc::Src::kXXXX));
|
||||
// r0.w for 4x MSAA = pixel Y in the group
|
||||
// r0.w for 2x MSAA = pixel Y in the group
|
||||
a.OpUShR(dxbc::Dest::R(0, 0b1000),
|
||||
dxbc::Src::VThreadIDInGroup(dxbc::Src::kYYYY), dxbc::Src::LU(1));
|
||||
// r0.w = free
|
||||
@@ -6067,7 +6101,7 @@ ID3D12PipelineState* D3D12RenderTargetCache::GetOrCreateDumpPipeline(
|
||||
if (key.msaa_samples != xenos::MsaaSamples::k1X) {
|
||||
// Sample index.
|
||||
// For 4x, bit 0 for horizontal, bit 1 for vertical.
|
||||
// For 2x, only vertical - but 0 or 1 for true 2x MSAA or 0 or 3 for 2x MSAA
|
||||
// For 2x, only vertical - but 1 or 0 for true 2x MSAA or 0 or 3 for 2x MSAA
|
||||
// via two samples of 4x.
|
||||
// r0.w = vertical sample index
|
||||
a.OpAnd(dxbc::Dest::R(0, 0b1000),
|
||||
@@ -6077,11 +6111,17 @@ ID3D12PipelineState* D3D12RenderTargetCache::GetOrCreateDumpPipeline(
|
||||
a.OpBFI(dxbc::Dest::R(0, 0b1000), dxbc::Src::LU(31), dxbc::Src::LU(1),
|
||||
dxbc::Src::R(0, dxbc::Src::kWWWW),
|
||||
dxbc::Src::VThreadIDInGroup(dxbc::Src::kXXXX));
|
||||
} else if (!msaa_2x_supported_) {
|
||||
// r0.w = source sample 0 or 3 for 2x MSAA emulated via 4x
|
||||
a.OpBFI(dxbc::Dest::R(0, 0b1000), dxbc::Src::LU(1), dxbc::Src::LU(1),
|
||||
dxbc::Src::R(0, dxbc::Src::kWWWW),
|
||||
dxbc::Src::R(0, dxbc::Src::kWWWW));
|
||||
} else {
|
||||
if (msaa_2x_supported_) {
|
||||
// r0.w = source sample 1 or 0 for native 2x MSAA
|
||||
a.OpXOr(dxbc::Dest::R(0, 0b1000), dxbc::Src::R(0, dxbc::Src::kWWWW),
|
||||
dxbc::Src::LU(1));
|
||||
} else {
|
||||
// r0.w = source sample 0 or 3 for 2x MSAA emulated via 4x
|
||||
a.OpBFI(dxbc::Dest::R(0, 0b1000), dxbc::Src::LU(1), dxbc::Src::LU(1),
|
||||
dxbc::Src::R(0, dxbc::Src::kWWWW),
|
||||
dxbc::Src::R(0, dxbc::Src::kWWWW));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user