diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp index 17085b1a23..d1f7d5ff93 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp @@ -16,13 +16,29 @@ size_t D3D12GSRender::UploadTextures() for (u32 i = 0; i < m_textures_count; ++i) { if (!m_textures[i].IsEnabled()) continue; + size_t w = m_textures[i].GetWidth(), h = m_textures[i].GetHeight(); // Upload at each iteration to take advantage of overlapping transfer ID3D12GraphicsCommandList *commandList; check(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, getCurrentResourceStorage().m_textureUploadCommandAllocator, nullptr, IID_PPV_ARGS(&commandList))); + DXGI_FORMAT dxgiFormat; + size_t pixelSize; + int format = m_textures[i].GetFormat() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); + switch (format) + { + default: + dxgiFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + pixelSize = 4; + break; + case CELL_GCM_TEXTURE_B8: + dxgiFormat = DXGI_FORMAT_R8_UNORM; + pixelSize = 1; + break; + } + ID3D12Resource *Texture, *vramTexture; - size_t textureSize = m_textures[i].GetWidth() * m_textures[i].GetHeight() * 4; + size_t textureSize = w * h * 4; D3D12_RESOURCE_DESC textureDesc = {}; textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; textureDesc.Width = textureSize; @@ -31,6 +47,7 @@ size_t D3D12GSRender::UploadTextures() textureDesc.SampleDesc.Count = 1; textureDesc.MipLevels = 1; textureDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + check(m_device->CreatePlacedResource( getCurrentResourceStorage().m_uploadTextureHeap, getCurrentResourceStorage().m_currentStorageOffset, @@ -44,14 +61,22 @@ size_t D3D12GSRender::UploadTextures() auto pixels = vm::get_ptr(texaddr); void *textureData; check(Texture->Map(0, nullptr, (void**)&textureData)); - memcpy(textureData, pixels, textureSize); + + // Multiple of 256 + size_t rowPitch = m_textures[i].GetWidth() * pixelSize; + rowPitch = (rowPitch + 255) & ~255; + // Upload with correct rowpitch + for (unsigned row = 0; row < m_textures[i].GetHeight(); row++) + { + memcpy((char*)textureData + row * rowPitch, pixels + row * m_textures[i].m_pitch, m_textures[i].m_pitch); + } Texture->Unmap(0, nullptr); D3D12_RESOURCE_DESC vramTextureDesc = {}; vramTextureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; vramTextureDesc.Width = m_textures[i].GetWidth(); vramTextureDesc.Height = m_textures[i].GetHeight(); - vramTextureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + vramTextureDesc.Format = dxgiFormat; vramTextureDesc.DepthOrArraySize = 1; vramTextureDesc.SampleDesc.Count = 1; vramTextureDesc.MipLevels = 1; @@ -67,6 +92,8 @@ size_t D3D12GSRender::UploadTextures() getCurrentResourceStorage().m_currentStorageOffset += textureSize; getCurrentResourceStorage().m_currentStorageOffset = (getCurrentResourceStorage().m_currentStorageOffset + 65536 - 1) & ~65535; + + D3D12_TEXTURE_COPY_LOCATION dst = {}, src = {}; dst.pResource = vramTexture; dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; @@ -75,8 +102,8 @@ size_t D3D12GSRender::UploadTextures() src.PlacedFootprint.Footprint.Depth = 1; src.PlacedFootprint.Footprint.Width = m_textures[i].GetWidth(); src.PlacedFootprint.Footprint.Height = m_textures[i].GetHeight(); - src.PlacedFootprint.Footprint.RowPitch = m_textures[i].GetWidth() * 4; - src.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + src.PlacedFootprint.Footprint.RowPitch = rowPitch; + src.PlacedFootprint.Footprint.Format = dxgiFormat; commandList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr); @@ -89,7 +116,7 @@ size_t D3D12GSRender::UploadTextures() D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; - srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + srvDesc.Format = dxgiFormat; srvDesc.Texture2D.MipLevels = 1; srvDesc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1, D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2, D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_3, D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0); D3D12_CPU_DESCRIPTOR_HANDLE Handle = getCurrentResourceStorage().m_textureDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(); @@ -98,7 +125,7 @@ size_t D3D12GSRender::UploadTextures() // TODO : Correctly define sampler D3D12_SAMPLER_DESC samplerDesc = {}; - samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; + samplerDesc.Filter = D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT; samplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; samplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; samplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;