Further improvements to FetchTexture2D.
This commit is contained in:
parent
efa7199974
commit
01b00118d4
|
@ -1105,7 +1105,15 @@ D3D11GraphicsDriver::TextureInfo D3D11GraphicsDriver::GetTextureInfo(
|
||||||
info.needs_power_of_two = false;
|
info.needs_power_of_two = false;
|
||||||
switch (fetch.format) {
|
switch (fetch.format) {
|
||||||
case FMT_8:
|
case FMT_8:
|
||||||
|
switch (fetch.swizzle) {
|
||||||
|
case XE_GPU_SWIZZLE_000R:
|
||||||
info.format = DXGI_FORMAT_A8_UNORM;
|
info.format = DXGI_FORMAT_A8_UNORM;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
XELOGW("D3D11: unhandled swizzle for FMT_8");
|
||||||
|
info.format = DXGI_FORMAT_A8_UNORM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
info.block_size = 1;
|
info.block_size = 1;
|
||||||
info.pitch = 1;
|
info.pitch = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -1132,7 +1140,15 @@ D3D11GraphicsDriver::TextureInfo D3D11GraphicsDriver::GetTextureInfo(
|
||||||
info.pitch = 4;
|
info.pitch = 4;
|
||||||
break;
|
break;
|
||||||
case FMT_4_4_4_4:
|
case FMT_4_4_4_4:
|
||||||
|
switch (fetch.swizzle) {
|
||||||
|
case XE_GPU_SWIZZLE_BGRA:
|
||||||
info.format = DXGI_FORMAT_B4G4R4A4_UNORM;
|
info.format = DXGI_FORMAT_B4G4R4A4_UNORM;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
XELOGW("D3D11: unhandled swizzle for FMT_4_4_4_4");
|
||||||
|
info.format = DXGI_FORMAT_B4G4R4A4_UNORM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
info.block_size = 1;
|
info.block_size = 1;
|
||||||
info.pitch = 2;
|
info.pitch = 2;
|
||||||
break;
|
break;
|
||||||
|
@ -1329,44 +1345,54 @@ int D3D11GraphicsDriver::FetchTexture2D(
|
||||||
XELOGE("D3D11: failed to map texture");
|
XELOGE("D3D11: failed to map texture");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto row_pitch = (width / info.block_size) * info.pitch;
|
||||||
|
auto padded_row_pitch = (padded_width / info.block_size) * info.pitch;
|
||||||
|
|
||||||
const uint8_t* src = memory_->Translate(address);
|
const uint8_t* src = memory_->Translate(address);
|
||||||
uint8_t* dest = (uint8_t*)res.pData;
|
uint8_t* dest = (uint8_t*)res.pData;
|
||||||
|
|
||||||
memset(dest, 0, res.RowPitch * (padded_height / info.block_size)); // TODO(gibbed): remove me later
|
memset(dest, 0, res.RowPitch * (padded_height / info.block_size)); // TODO(gibbed): remove me later
|
||||||
|
|
||||||
auto row_pitch = (width / info.block_size) * info.pitch;
|
|
||||||
auto padded_row_pitch = (padded_width / info.block_size) * info.pitch;
|
|
||||||
|
|
||||||
if (false) { // TODO(gibbed): if for some reason we ever want to not swap?
|
|
||||||
for (size_t y = 0; y < height / info.block_size; y++) {
|
|
||||||
memcpy(dest, src, row_pitch);
|
|
||||||
src += padded_row_pitch;
|
|
||||||
dest += res.RowPitch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!fetch.tiled) {
|
if (!fetch.tiled) {
|
||||||
for (uint32_t y = 0; y < height / info.block_size; y++) {
|
for (uint32_t y = 0; y < height / info.block_size; y++) {
|
||||||
for (uint32_t x = 0; x < row_pitch; x += info.pitch) {
|
for (uint32_t x = 0; x < row_pitch; x += 4) {
|
||||||
TextureSwap(dest + x, src + x, info.pitch, (XE_GPU_ENDIAN)fetch.endianness);
|
*(uint32_t*)(dest + x) = XESWAP32BE(*(uint32_t*)(src + x));
|
||||||
}
|
}
|
||||||
src += padded_row_pitch;
|
src += padded_row_pitch;
|
||||||
dest += res.RowPitch;
|
dest += res.RowPitch;
|
||||||
}
|
}
|
||||||
|
src = NULL;
|
||||||
|
dest = (uint8_t*)res.pData;
|
||||||
|
for (uint32_t y = 0; y < height / info.block_size; y++) {
|
||||||
|
for (uint32_t x = 0; x < row_pitch; x += info.pitch) {
|
||||||
|
TextureSwap(dest + x, dest + x, info.pitch, (XE_GPU_ENDIAN)fetch.endianness);
|
||||||
|
}
|
||||||
|
dest += res.RowPitch;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
uint8_t* temp = (uint8_t*)xe_calloc(height * res.RowPitch);
|
||||||
|
dest = temp;
|
||||||
|
for (uint32_t y = 0; y < height / info.block_size; y++) {
|
||||||
|
for (uint32_t x = 0; x < row_pitch; x += 4) {
|
||||||
|
*(uint32_t*)(dest + x) = XESWAP32BE(*(uint32_t*)(src + x));
|
||||||
|
}
|
||||||
|
src += padded_row_pitch;
|
||||||
|
dest += res.RowPitch;
|
||||||
|
}
|
||||||
|
dest = (uint8_t*)res.pData;
|
||||||
auto aligned_width = (width + 31) & ~31; // 32x32
|
auto aligned_width = (width + 31) & ~31; // 32x32
|
||||||
auto log_bpp = (info.pitch >> 2) + ((info.pitch >> 1) >> (info.pitch >> 2));
|
auto log_bpp = (info.pitch >> 2) + ((info.pitch >> 1) >> (info.pitch >> 2));
|
||||||
for (uint32_t y = 0; y < height; y++) {
|
for (uint32_t y = 0; y < height; y++) {
|
||||||
auto base_offset = TiledOffset2DOuter(y, aligned_width, log_bpp);
|
auto base_offset = TiledOffset2DOuter(y, aligned_width, log_bpp);
|
||||||
for (uint32_t x = 0; x < width; x++) {
|
for (uint32_t x = 0; x < width; x++) {
|
||||||
auto offset = TiledOffset2DInner(x, y, log_bpp, base_offset);
|
auto offset = TiledOffset2DInner(x, y, log_bpp, base_offset);
|
||||||
TextureSwap(dest + (y * res.RowPitch) + (x * info.pitch), src + offset, info.pitch, (XE_GPU_ENDIAN)fetch.endianness);
|
TextureSwap(dest + (y * res.RowPitch) + (x * info.pitch), temp + offset, info.pitch, (XE_GPU_ENDIAN)fetch.endianness);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
xe_free(temp);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
context_->Unmap(*out_texture, 0);
|
context_->Unmap(*out_texture, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue