Drivers and hardware may provide more optimal paths for untyped buffers compared to typed. Also, ByteAddressBuffer may be bound via a root descriptor in Direct3D 12, greatly simplifying the binding logic. ByteAddressBuffer also doesn't have the 128 * 2^20 element count limit that typed and structured buffers have, and doesn't require the structure stride to be specified at resource creation time in Direct3D 11.
68 lines
2.7 KiB
Plaintext
68 lines
2.7 KiB
Plaintext
/**
|
|
******************************************************************************
|
|
* Xenia : Xbox 360 Emulator Research Project *
|
|
******************************************************************************
|
|
* Copyright 2022 Ben Vanik. All rights reserved. *
|
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
******************************************************************************
|
|
*/
|
|
|
|
#include "endian.xesli"
|
|
#include "pixel_formats.xesli"
|
|
#define XE_RESOLVE_COPY_EDRAM_BYTE_BUFFER_ALIGNMENT 4
|
|
#include "resolve.xesli"
|
|
|
|
byte_buffer_align16_wo_declare_xe(xe_resolve_dest, set=1, binding=0, u0, space0)
|
|
#define LOCAL_SIZE_X_XE 8
|
|
#define LOCAL_SIZE_Y_XE 8
|
|
#define LOCAL_SIZE_Z_XE 1
|
|
entry_bindings_begin_compute_xe
|
|
XE_RESOLVE_PUSH_CONST_BINDING
|
|
entry_binding_next_xe
|
|
byte_buffer_wo_binding_xe(xe_resolve_dest, buffer(1))
|
|
entry_binding_next_xe
|
|
XE_RESOLVE_COPY_EDRAM_BINDING
|
|
entry_bindings_end_inputs_begin_compute_xe
|
|
entry_in_global_thread_id_xe
|
|
entry_inputs_end_code_begin_compute_xe
|
|
{
|
|
// 1 thread = 4 host pixels.
|
|
XeResolveInfo resolve_info = XeResolveGetInfo(pass_push_consts_xe);
|
|
uint2_xe pixel_index = in_global_thread_id_xe.xy << uint2_xe(2u, 0u);
|
|
// Group height can't cross resolve granularity, Y overflow check not needed.
|
|
dont_flatten_xe
|
|
if (pixel_index.x >= resolve_info.width_div_8_scaled << 3u) {
|
|
return;
|
|
}
|
|
float4_xe pixel_0, pixel_1, pixel_2, pixel_3;
|
|
XeResolveLoad4RGBAColors(
|
|
pass_byte_buffer_xe(xe_resolve_edram) pass_next_after_byte_buffer_xe
|
|
resolve_info,
|
|
XeResolveColorCopySourcePixelAddressBytesYHalfPixelOffsetFilling(
|
|
resolve_info, pixel_index),
|
|
pixel_0, pixel_1, pixel_2, pixel_3);
|
|
uint4_xe packed_01, packed_23;
|
|
XePack64bpp4Pixels(pixel_0, pixel_1, pixel_2, pixel_3,
|
|
resolve_info.dest_format, packed_01, packed_23);
|
|
dont_flatten_xe
|
|
if (pixel_index.x == 0u &&
|
|
resolve_info.half_pixel_offset_fill_source.x != 0u) {
|
|
if (resolve_info.half_pixel_offset_fill_source.x >= 2u) {
|
|
if (resolve_info.half_pixel_offset_fill_source.x >= 3u) {
|
|
packed_23.xy = packed_23.zw;
|
|
}
|
|
packed_01.zw = packed_23.xy;
|
|
}
|
|
packed_01.xy = packed_01.zw;
|
|
}
|
|
uint dest_address = XeResolveDestPixelAddress(resolve_info, pixel_index, 3u);
|
|
byte_buffer_align16_store16_xe(
|
|
xe_resolve_dest, dest_address,
|
|
XeEndianSwap64(packed_01, resolve_info.dest_endian_128));
|
|
dest_address += XeResolveLocalXAddressXor(2u, 3u);
|
|
byte_buffer_align16_store16_xe(
|
|
xe_resolve_dest, dest_address,
|
|
XeEndianSwap64(packed_23, resolve_info.dest_endian_128));
|
|
}
|
|
entry_code_end_compute_xe
|