[GPU] Add texture_util::SwizzleSigns for later
This commit is contained in:
parent
b256005b7a
commit
a3b4c77fdb
|
@ -2160,6 +2160,7 @@ void TextureCache::BindingInfoFromFetchConstant(
|
||||||
*swizzle_out = swizzle;
|
*swizzle_out = swizzle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(Triang3l): Move to texture_util::SwizzleSigns.
|
||||||
if (has_unsigned_out != nullptr) {
|
if (has_unsigned_out != nullptr) {
|
||||||
*has_unsigned_out = fetch.sign_x != TextureSign::kSigned ||
|
*has_unsigned_out = fetch.sign_x != TextureSign::kSigned ||
|
||||||
fetch.sign_y != TextureSign::kSigned ||
|
fetch.sign_y != TextureSign::kSigned ||
|
||||||
|
|
|
@ -2520,6 +2520,7 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
|
||||||
// linearization must be done on color values in 0...1 range, and this
|
// linearization must be done on color values in 0...1 range, and this
|
||||||
// is closer to the storage format, while exponent bias is closer to the
|
// is closer to the storage format, while exponent bias is closer to the
|
||||||
// actual usage in shaders.
|
// actual usage in shaders.
|
||||||
|
// TODO(Triang3l): Signs should be pre-swizzled.
|
||||||
for (uint32_t i = 0; i < 4; ++i) {
|
for (uint32_t i = 0; i < 4; ++i) {
|
||||||
// Extract the sign values from dword 0 ([0].x or [1].z) of the fetch
|
// Extract the sign values from dword 0 ([0].x or [1].z) of the fetch
|
||||||
// constant (in bits 2:9, 2 bits per component) to sign_temp.x.
|
// constant (in bits 2:9, 2 bits per component) to sign_temp.x.
|
||||||
|
|
|
@ -340,6 +340,43 @@ int32_t GetTiledOffset3D(int32_t x, int32_t y, int32_t z, uint32_t width,
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t SwizzleSigns(const xenos::xe_gpu_texture_fetch_t& fetch,
|
||||||
|
bool* any_unsigned_out, bool* any_signed_out) {
|
||||||
|
uint32_t signs = 0;
|
||||||
|
bool any_unsigned = false, any_signed = false;
|
||||||
|
// 0b00 or 0b01 for each component, whether it's constant 0/1.
|
||||||
|
uint32_t constant_mask = 0b00000000;
|
||||||
|
for (uint32_t i = 0; i < 4; ++i) {
|
||||||
|
uint32_t swizzle = (fetch.swizzle >> (i * 3)) & 0b111;
|
||||||
|
if (swizzle & 0b100) {
|
||||||
|
constant_mask |= 1 << (i * 2);
|
||||||
|
} else {
|
||||||
|
TextureSign sign =
|
||||||
|
TextureSign((fetch.dword_0 >> (2 + swizzle * 2)) & 0b11);
|
||||||
|
signs |= uint32_t(sign) << (i * 2);
|
||||||
|
if (sign == TextureSign::kSigned) {
|
||||||
|
any_signed = true;
|
||||||
|
} else {
|
||||||
|
any_unsigned = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (any_signed && !any_unsigned) {
|
||||||
|
// If only signed and constant components, reading just from the signed host
|
||||||
|
// view is enough.
|
||||||
|
signs |= uint32_t(TextureSign::kSigned) * constant_mask;
|
||||||
|
} else {
|
||||||
|
signs |= uint32_t(TextureSign::kUnsigned) * constant_mask;
|
||||||
|
}
|
||||||
|
if (any_unsigned_out) {
|
||||||
|
*any_unsigned_out = any_unsigned;
|
||||||
|
}
|
||||||
|
if (any_signed_out) {
|
||||||
|
*any_signed_out = any_signed;
|
||||||
|
}
|
||||||
|
return signs;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace texture_util
|
} // namespace texture_util
|
||||||
} // namespace gpu
|
} // namespace gpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
|
@ -88,6 +88,17 @@ int32_t GetTiledOffset2D(int32_t x, int32_t y, uint32_t width,
|
||||||
int32_t GetTiledOffset3D(int32_t x, int32_t y, int32_t z, uint32_t width,
|
int32_t GetTiledOffset3D(int32_t x, int32_t y, int32_t z, uint32_t width,
|
||||||
uint32_t height, uint32_t bpb_log2);
|
uint32_t height, uint32_t bpb_log2);
|
||||||
|
|
||||||
|
// Returns four packed TextureSign values swizzled according to the swizzle in
|
||||||
|
// the fetch constant, so the shader can apply TextureSigns after reading a
|
||||||
|
// pre-swizzled texture. 0/1 elements are considered unsigned (and not biased),
|
||||||
|
// however, if all non-constant components are signed, 0/1 are considered signed
|
||||||
|
// too (because in backends, unsigned and signed textures may use separate views
|
||||||
|
// with different formats, so just one view is used for both signed and constant
|
||||||
|
// components).
|
||||||
|
uint32_t SwizzleSigns(const xenos::xe_gpu_texture_fetch_t& fetch,
|
||||||
|
bool* any_unsigned_out = nullptr,
|
||||||
|
bool* any_signed_out = nullptr);
|
||||||
|
|
||||||
} // namespace texture_util
|
} // namespace texture_util
|
||||||
} // namespace gpu
|
} // namespace gpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
|
@ -657,6 +657,12 @@ XEPACKEDUNION(xe_gpu_vertex_fetch_t, {
|
||||||
XEPACKEDUNION(xe_gpu_texture_fetch_t, {
|
XEPACKEDUNION(xe_gpu_texture_fetch_t, {
|
||||||
XEPACKEDSTRUCTANONYMOUS({
|
XEPACKEDSTRUCTANONYMOUS({
|
||||||
FetchConstantType type : 2; // +0 dword_0
|
FetchConstantType type : 2; // +0 dword_0
|
||||||
|
// Likely before the swizzle, seems logical from R5xx (SIGNED_COMP0/1/2/3
|
||||||
|
// set the signedness of components 0/1/2/3, while SEL_ALPHA/RED/GREEN/BLUE
|
||||||
|
// specify "swizzling for each channel at the input of the pixel shader",
|
||||||
|
// which can be texture components 0/1/2/3 or constant 0/1) and R6xx
|
||||||
|
// (signedness is FORMAT_COMP_X/Y/Z/W, while the swizzle is DST_SEL_X/Y/Z/W,
|
||||||
|
// which is named in resources the same as DST_SEL in fetch clauses).
|
||||||
TextureSign sign_x : 2; // +2
|
TextureSign sign_x : 2; // +2
|
||||||
TextureSign sign_y : 2; // +4
|
TextureSign sign_y : 2; // +4
|
||||||
TextureSign sign_z : 2; // +6
|
TextureSign sign_z : 2; // +6
|
||||||
|
|
Loading…
Reference in New Issue