From 6fae5863cfb4337e20620a9ebf29b425f3e9f22b Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 28 Nov 2015 01:57:05 +0100 Subject: [PATCH 01/13] common/d3d12/gl: Add support for textureProj --- rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp | 2 +- rpcs3/Emu/RSX/Common/ShaderParam.h | 1 + rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp | 2 ++ rpcs3/Emu/RSX/GL/GLCommonDecompiler.cpp | 2 ++ 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp index 1a5eb44191..482f5ea390 100644 --- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp @@ -423,7 +423,7 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode) case RSX_FP_OPCODE_BEM: LOG_ERROR(RSX, "Unimplemented TEX_SRB instruction: BEM"); return true; case RSX_FP_OPCODE_TEX: SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE)); return true; case RSX_FP_OPCODE_TEXBEM: SetDst("texture($t, $0.xy, $1.x)"); return true; - case RSX_FP_OPCODE_TXP: SetDst("textureProj($t, $0.xyz, $1.x)"); return true; //TODO: More testing (Sonic The Hedgehog (NPUB-30442/NPEB-00478) and The Simpsons Arcade Game (NPUB30563)) + case RSX_FP_OPCODE_TXP: SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE_PROJ)); return true; //TODO: More testing (Sonic The Hedgehog (NPUB-30442/NPEB-00478) and The Simpsons Arcade Game (NPUB30563)) case RSX_FP_OPCODE_TXPBEM: SetDst("textureProj($t, $0.xyz, $1.x)"); return true; case RSX_FP_OPCODE_TXD: LOG_ERROR(RSX, "Unimplemented TEX_SRB instruction: TXD"); return true; case RSX_FP_OPCODE_TXB: SetDst("texture($t, $0.xy, $1.x)"); return true; diff --git a/rpcs3/Emu/RSX/Common/ShaderParam.h b/rpcs3/Emu/RSX/Common/ShaderParam.h index ae30e4bf69..cfeb5c5911 100644 --- a/rpcs3/Emu/RSX/Common/ShaderParam.h +++ b/rpcs3/Emu/RSX/Common/ShaderParam.h @@ -14,6 +14,7 @@ enum class FUNCTION { FUNCTION_DFDX, FUNCTION_DFDY, FUNCTION_TEXTURE_SAMPLE, + FUNCTION_TEXTURE_SAMPLE_PROJ, }; enum class COMPARE { diff --git a/rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp index de1ff130ab..786c75ff9b 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp @@ -44,6 +44,8 @@ std::string getFunctionImp(FUNCTION f) return "frac($0)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLE: return "$t.Sample($tsampler, $0.xy * $t_scale)"; + case FUNCTION::FUNCTION_TEXTURE_SAMPLE_PROJ: + return "$t.Sample($tsampler, ($0.xy / $0.z) * $t_scale)"; case FUNCTION::FUNCTION_DFDX: return "ddx($0)"; case FUNCTION::FUNCTION_DFDY: diff --git a/rpcs3/Emu/RSX/GL/GLCommonDecompiler.cpp b/rpcs3/Emu/RSX/GL/GLCommonDecompiler.cpp index 808646b4d8..c4fb1c0d1d 100644 --- a/rpcs3/Emu/RSX/GL/GLCommonDecompiler.cpp +++ b/rpcs3/Emu/RSX/GL/GLCommonDecompiler.cpp @@ -42,6 +42,8 @@ std::string getFunctionImpl(FUNCTION f) return "fract($0)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLE: return "texture($t, $0.xy)"; + case FUNCTION::FUNCTION_TEXTURE_SAMPLE_PROJ: + return "textureProj($t, $0.xyz, $1.x)"; // Note: $1.x is bias case FUNCTION::FUNCTION_DFDX: return "dFdx($0)"; case FUNCTION::FUNCTION_DFDY: From 929f518ef3b2a932e5bfdb20c12117767c071d90 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Mon, 30 Nov 2015 19:39:14 +0100 Subject: [PATCH 02/13] rsx/d3d12/gl: Make output write backend dependent. --- .../RSX/Common/FragmentProgramDecompiler.cpp | 5 ---- .../D3D12/D3D12FragmentProgramDecompiler.cpp | 28 +++++++++++++------ rpcs3/Emu/RSX/GCM.h | 6 ++++ rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp | 20 +++++++------ 4 files changed, 37 insertions(+), 22 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp index 482f5ea390..0831194f15 100644 --- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp @@ -319,11 +319,6 @@ std::string FragmentProgramDecompiler::BuildCode() { //main += fmt::format("\tgl_FragColor = %c0;\n", m_ctrl & 0x40 ? 'r' : 'h'); - if (m_ctrl & 0xe) - { - main += m_ctrl & 0x40 ? "\tgl_FragDepth = r1.z;\n" : "\tgl_FragDepth = h0.z;\n"; - } - std::stringstream OS; insertHeader(OS); OS << std::endl; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp index ef46afafc5..8e5daf93ee 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp @@ -88,10 +88,10 @@ void D3D12FragmentDecompiler::insertOutputs(std::stringstream & OS) OS << "{" << std::endl; const std::pair table[] = { - { "ocol0", m_ctrl & 0x40 ? "r0" : "h0" }, - { "ocol1", m_ctrl & 0x40 ? "r2" : "h4" }, - { "ocol2", m_ctrl & 0x40 ? "r3" : "h6" }, - { "ocol3", m_ctrl & 0x40 ? "r4" : "h8" }, + { "ocol0", m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS ? "r0" : "h0" }, + { "ocol1", m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS ? "r2" : "h4" }, + { "ocol2", m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS ? "r3" : "h6" }, + { "ocol3", m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS ? "r4" : "h8" }, }; for (int i = 0; i < sizeof(table) / sizeof(*table); ++i) @@ -99,6 +99,8 @@ void D3D12FragmentDecompiler::insertOutputs(std::stringstream & OS) if (m_parr.HasParam(PF_PARAM_NONE, "float4", table[i].second)) OS << " " << "float4" << " " << table[i].first << " : SV_TARGET" << i << ";" << std::endl; } + if (m_ctrl & CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT) + OS << " float depth : SV_Depth;" << std::endl; OS << "};" << std::endl; } @@ -166,19 +168,27 @@ void D3D12FragmentDecompiler::insertMainEnd(std::stringstream & OS) { const std::pair table[] = { - { "ocol0", m_ctrl & 0x40 ? "r0" : "h0" }, - { "ocol1", m_ctrl & 0x40 ? "r2" : "h4" }, - { "ocol2", m_ctrl & 0x40 ? "r3" : "h6" }, - { "ocol3", m_ctrl & 0x40 ? "r4" : "h8" }, + { "ocol0", m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS ? "r0" : "h0" }, + { "ocol1", m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS ? "r2" : "h4" }, + { "ocol2", m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS ? "r3" : "h6" }, + { "ocol3", m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS ? "r4" : "h8" }, }; OS << " PixelOutput Out;" << std::endl; + size_t num_output = 0; for (int i = 0; i < sizeof(table) / sizeof(*table); ++i) { if (m_parr.HasParam(PF_PARAM_NONE, "float4", table[i].second)) + { OS << " Out." << table[i].first << " = " << table[i].second << ";" << std::endl; + num_output++; + } } - OS << " if (isAlphaTested && Out.ocol0.a <= alphaRef) discard;" << std::endl; + if (m_ctrl & CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT) + OS << " Out.depth = " << ((m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS) ? "r1.z;" : "h0.z;") << std::endl; + // Shaders don't always output colors (for instance if they write to depth only) + if (num_output > 0) + OS << " if (isAlphaTested && Out.ocol0.a <= alphaRef) discard;" << std::endl; OS << " return Out;" << std::endl; OS << "}" << std::endl; } diff --git a/rpcs3/Emu/RSX/GCM.h b/rpcs3/Emu/RSX/GCM.h index 16d9fe09cd..156b69837c 100644 --- a/rpcs3/Emu/RSX/GCM.h +++ b/rpcs3/Emu/RSX/GCM.h @@ -454,6 +454,12 @@ enum CELL_GCM_FALSE = 0 }; +enum +{ + CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT = 0xe, ///< shader program exports the depth of the shaded fragment + CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS = 0x40 ///< shader program exports 32 bits registers values (instead of 16 bits ones) +}; + // GCM Reports enum { diff --git a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp index 3ece495c60..2bf09ea511 100644 --- a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp @@ -5,6 +5,7 @@ #include "GLFragmentProgram.h" #include "GLCommonDecompiler.h" +#include "../GCM.h" std::string GLFragmentDecompilerThread::getFloatTypeName(size_t elementCount) { @@ -44,10 +45,10 @@ void GLFragmentDecompilerThread::insertOutputs(std::stringstream & OS) { const std::pair table[] = { - { "ocol0", m_ctrl & 0x40 ? "r0" : "h0" }, - { "ocol1", m_ctrl & 0x40 ? "r2" : "h4" }, - { "ocol2", m_ctrl & 0x40 ? "r3" : "h6" }, - { "ocol3", m_ctrl & 0x40 ? "r4" : "h8" }, + { "ocol0", m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS ? "r0" : "h0" }, + { "ocol1", m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS ? "r2" : "h4" }, + { "ocol2", m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS ? "r3" : "h6" }, + { "ocol3", m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS ? "r4" : "h8" }, }; for (int i = 0; i < sizeof(table) / sizeof(*table); ++i) @@ -103,10 +104,10 @@ void GLFragmentDecompilerThread::insertMainEnd(std::stringstream & OS) { const std::pair table[] = { - { "ocol0", m_ctrl & 0x40 ? "r0" : "h0" }, - { "ocol1", m_ctrl & 0x40 ? "r2" : "h4" }, - { "ocol2", m_ctrl & 0x40 ? "r3" : "h6" }, - { "ocol3", m_ctrl & 0x40 ? "r4" : "h8" }, + { "ocol0", m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS ? "r0" : "h0" }, + { "ocol1", m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS ? "r2" : "h4" }, + { "ocol2", m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS ? "r3" : "h6" }, + { "ocol3", m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS ? "r4" : "h8" }, }; for (int i = 0; i < sizeof(table) / sizeof(*table); ++i) @@ -115,6 +116,9 @@ void GLFragmentDecompilerThread::insertMainEnd(std::stringstream & OS) OS << " " << table[i].first << " = " << table[i].second << ";" << std::endl; } + if (m_ctrl & CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT) + OS << ((m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS) ? "\tgl_FragDepth = r1.z;\n" : "\tgl_FragDepth = h0.z;\n") << std::endl; + OS << "}" << std::endl; } From 80dc1227429d54fa6352e93e026cc52f86f5de8f Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Mon, 7 Dec 2015 22:09:18 +0100 Subject: [PATCH 03/13] common/d3d12: Clean texture upload code. Some typos are fixed in the process --- rpcs3/Emu/RSX/Common/TextureUtils.cpp | 301 ++++++++++---------------- 1 file changed, 110 insertions(+), 191 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.cpp b/rpcs3/Emu/RSX/Common/TextureUtils.cpp index 1aa78dbc72..fae7e941d0 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.cpp +++ b/rpcs3/Emu/RSX/Common/TextureUtils.cpp @@ -11,222 +11,136 @@ namespace /** * Write data, assume src pixels are packed but not mipmaplevel */ -std::vector -writeTexelsGeneric(const char *src, char *dst, size_t widthInBlock, size_t heightInBlock, size_t blockSize, size_t mipmapCount) +struct texel_rgba { - std::vector Result; - size_t offsetInDst = 0, offsetInSrc = 0; - size_t currentHeight = heightInBlock, currentWidth = widthInBlock; - for (unsigned mipLevel = 0; mipLevel < mipmapCount; mipLevel++) + template + static size_t copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block) noexcept { - size_t rowPitch = align(currentWidth * blockSize, 256); - - MipmapLevelInfo currentMipmapLevelInfo = {}; - currentMipmapLevelInfo.offset = offsetInDst; - currentMipmapLevelInfo.height = currentHeight; - currentMipmapLevelInfo.width = currentWidth; - currentMipmapLevelInfo.rowPitch = rowPitch; - Result.push_back(currentMipmapLevelInfo); - - for (unsigned row = 0; row < currentHeight; row++) - memcpy((char*)dst + offsetInDst + row * rowPitch, (char*)src + offsetInSrc + row * widthInBlock * blockSize, currentWidth * blockSize); - - offsetInDst += currentHeight * rowPitch; - offsetInDst = align(offsetInDst, 512); - offsetInSrc += currentHeight * widthInBlock * blockSize; - currentHeight = MAX2(currentHeight / 2, 1); - currentWidth = MAX2(currentWidth / 2, 1); + for (unsigned row = 0; row < row_count; row++) + memcpy((char*)dst + row * dst_pitch_in_block * block_size, (char*)src + row * src_pitch_in_block * block_size, width_in_block * block_size); + return row_count * src_pitch_in_block * block_size; } - return Result; -} - -/** -* Write data, assume src pixels are swizzled and but not mipmaplevel -*/ -std::vector -writeTexelsSwizzled(const char *src, char *dst, size_t widthInBlock, size_t heightInBlock, size_t blockSize, size_t mipmapCount) -{ - std::vector Result; - size_t offsetInDst = 0, offsetInSrc = 0; - size_t currentHeight = heightInBlock, currentWidth = widthInBlock; - for (unsigned mipLevel = 0; mipLevel < mipmapCount; mipLevel++) - { - size_t rowPitch = align(currentWidth * blockSize, 256); - - MipmapLevelInfo currentMipmapLevelInfo = {}; - currentMipmapLevelInfo.offset = offsetInDst; - currentMipmapLevelInfo.height = currentHeight; - currentMipmapLevelInfo.width = currentWidth; - currentMipmapLevelInfo.rowPitch = rowPitch; - Result.push_back(currentMipmapLevelInfo); - - u32 *castedSrc, *castedDst; - - castedSrc = (u32*)src + offsetInSrc; - castedDst = (u32*)dst + offsetInDst; - - std::unique_ptr temp_swizzled(new u32[currentHeight * currentWidth]); - rsx::convert_linear_swizzle(castedSrc, temp_swizzled.get(), currentWidth, currentHeight, true); - for (unsigned row = 0; row < currentHeight; row++) - memcpy((char*)dst + offsetInDst + row * rowPitch, (char*)temp_swizzled.get() + offsetInSrc + row * widthInBlock * blockSize, currentWidth * blockSize); - - offsetInDst += currentHeight * rowPitch; - offsetInSrc += currentHeight * widthInBlock * blockSize; - currentHeight = MAX2(currentHeight / 2, 1); - currentWidth = MAX2(currentWidth / 2, 1); - } - return Result; -} - - -/** -* Write data, assume compressed (DXTCn) format -*/ -std::vector -writeCompressedTexel(const char *src, char *dst, size_t widthInBlock, size_t blockWidth, size_t heightInBlock, size_t blockHeight, size_t blockSize, size_t mipmapCount) -{ - std::vector Result; - size_t offsetInDst = 0, offsetInSrc = 0; - size_t currentHeight = heightInBlock, currentWidth = widthInBlock; - for (unsigned mipLevel = 0; mipLevel < mipmapCount; mipLevel++) - { - size_t rowPitch = align(currentWidth * blockSize, 256); - - MipmapLevelInfo currentMipmapLevelInfo = {}; - currentMipmapLevelInfo.offset = offsetInDst; - currentMipmapLevelInfo.height = currentHeight * blockHeight; - currentMipmapLevelInfo.width = currentWidth * blockWidth; - currentMipmapLevelInfo.rowPitch = rowPitch; - Result.push_back(currentMipmapLevelInfo); - - for (unsigned row = 0; row < currentHeight; row++) - memcpy((char*)dst + offsetInDst + row * rowPitch, (char*)src + offsetInSrc + row * currentWidth * blockSize, currentWidth * blockSize); - - offsetInDst += currentHeight * rowPitch; - offsetInDst = align(offsetInDst, 512); - offsetInSrc += currentHeight * currentWidth * blockSize; - currentHeight = MAX2(currentHeight / 2, 1); - currentWidth = MAX2(currentWidth / 2, 1); - } - return Result; -} +}; /** * Write 16 bytes pixel textures, assume src pixels are swizzled and but not mipmaplevel */ -std::vector -write16bTexelsSwizzled(const char *src, char *dst, size_t widthInBlock, size_t heightInBlock, size_t blockSize, size_t mipmapCount) +struct texel_16b_swizzled { - std::vector Result; - size_t offsetInDst = 0, offsetInSrc = 0; - size_t currentHeight = heightInBlock, currentWidth = widthInBlock; - size_t srcPitch = widthInBlock * blockSize; - for (unsigned mipLevel = 0; mipLevel < mipmapCount; mipLevel++) + template + static size_t copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block) noexcept { - size_t rowPitch = align(currentWidth * blockSize, 256); + u16 *castedSrc = static_cast(src), *castedDst = static_cast(dst); - MipmapLevelInfo currentMipmapLevelInfo = {}; - currentMipmapLevelInfo.offset = offsetInDst; - currentMipmapLevelInfo.height = currentHeight; - currentMipmapLevelInfo.width = currentWidth; - currentMipmapLevelInfo.rowPitch = rowPitch; - Result.push_back(currentMipmapLevelInfo); - - u16 *castedSrc, *castedDst; - - castedSrc = (u16*)src + offsetInSrc; - castedDst = (u16*)dst + offsetInDst; - - std::unique_ptr temp_swizzled(new u16[currentHeight * currentWidth]); - rsx::convert_linear_swizzle(castedSrc, temp_swizzled.get(), currentWidth, currentHeight, true); - for (unsigned row = 0; row < heightInBlock; row++) - for (int j = 0; j < currentWidth; j++) + std::unique_ptr temp_swizzled(new u16[row_count * width_in_block]); + rsx::convert_linear_swizzle(castedSrc, temp_swizzled.get(), src_pitch_in_block, row_count, true); + for (unsigned row = 0; row < row_count; row++) + for (int j = 0; j < width_in_block; j++) { - u16 tmp = temp_swizzled[offsetInSrc / 2 + row * srcPitch / 2 + j]; - castedDst[offsetInDst / 2 + row * rowPitch / 2 + j] = (tmp >> 8) | (tmp << 8); + u16 tmp = temp_swizzled[row * src_pitch_in_block + j]; + castedDst[row * dst_pitch_in_block + j] = (tmp >> 8) | (tmp << 8); } - - offsetInDst += currentHeight * rowPitch; - offsetInSrc += currentHeight * widthInBlock * blockSize; - currentHeight = MAX2(currentHeight / 2, 1); - currentWidth = MAX2(currentWidth / 2, 1); + return row_count * src_pitch_in_block * block_size; } - return Result; -} +}; + +/** +* Write data, assume src pixels are swizzled and but not mipmaplevel +*/ +struct texel_rgba_swizzled +{ + template + static size_t copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block) noexcept + { + u32 *castedSrc, *castedDst; + castedSrc = (u32*)src; + castedDst = (u32*)dst ; + std::unique_ptr temp_swizzled(new u32[src_pitch_in_block * row_count]); + rsx::convert_linear_swizzle(castedSrc, temp_swizzled.get(), src_pitch_in_block, row_count, true); + for (unsigned row = 0; row < row_count; row++) + memcpy((char*)dst + row * dst_pitch_in_block * block_size, (char*)temp_swizzled.get() + row * src_pitch_in_block * block_size, width_in_block * block_size); + return row_count * src_pitch_in_block * block_size; + } +}; + +/** + * Write data, assume compressed (DXTCn) format + * Data are tightly packed + */ +struct texel_bc_format { + template + static size_t copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block) noexcept + { + for (unsigned row = 0; row < row_count; row++) + memcpy((char*)dst + row * dst_pitch_in_block * block_size, (char*)src + row * width_in_block * block_size, width_in_block * block_size); + return width_in_block * row_count * block_size; + } +}; /** * Write 16 bytes pixel textures, assume src pixels are packed but not mipmaplevel */ -std::vector -write16bTexelsGeneric(const char *src, char *dst, size_t widthInBlock, size_t heightInBlock, size_t blockSize, size_t mipmapCount) -{ - std::vector Result; - size_t offsetInDst = 0, offsetInSrc = 0; - size_t currentHeight = heightInBlock, currentWidth = widthInBlock; - size_t srcPitch = widthInBlock * blockSize; - for (unsigned mipLevel = 0; mipLevel < mipmapCount; mipLevel++) +struct texel_16b_format { + template + static size_t copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block) noexcept { - size_t rowPitch = align(currentWidth * blockSize, 256); - - MipmapLevelInfo currentMipmapLevelInfo = {}; - currentMipmapLevelInfo.offset = offsetInDst; - currentMipmapLevelInfo.height = currentHeight; - currentMipmapLevelInfo.width = currentWidth; - currentMipmapLevelInfo.rowPitch = rowPitch; - Result.push_back(currentMipmapLevelInfo); - unsigned short *castedDst = (unsigned short *)dst, *castedSrc = (unsigned short *)src; - for (unsigned row = 0; row < heightInBlock; row++) - for (int j = 0; j < currentWidth; j++) + for (unsigned row = 0; row < row_count; row++) + for (int j = 0; j < width_in_block; j++) { - u16 tmp = castedSrc[offsetInSrc / 2 + row * srcPitch / 2 + j]; - castedDst[offsetInDst / 2 + row * rowPitch / 2 + j] = (tmp >> 8) | (tmp << 8); + u16 tmp = castedSrc[row * src_pitch_in_block + j]; + castedDst[row * dst_pitch_in_block + j] = (tmp >> 8) | (tmp << 8); } - - offsetInDst += currentHeight * rowPitch; - offsetInSrc += currentHeight * widthInBlock * blockSize; - currentHeight = MAX2(currentHeight / 2, 1); - currentWidth = MAX2(currentWidth / 2, 1); + return row_count * src_pitch_in_block * block_size; } - return Result; -} +}; /** -* Write 16 bytes pixel textures, assume src pixels are packed but not mipmaplevel +* Write 16 bytes X 4 pixel textures, assume src pixels are packed but not mipmaplevel */ -std::vector -write16bX4TexelsGeneric(const char *src, char *dst, size_t widthInBlock, size_t heightInBlock, size_t blockSize, size_t mipmapCount) +struct texel_16bX4_format { + template + static size_t copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block) noexcept + { + unsigned short *casted_dst = (unsigned short *)dst, *casted_src = (unsigned short *)src; + for (unsigned row = 0; row < row_count; row++) + for (int j = 0; j < width_in_block * 4; j++) + { + u16 tmp = casted_src[row * src_pitch_in_block * 4 + j]; + casted_dst[row * dst_pitch_in_block * 4 + j] = (tmp >> 8) | (tmp << 8); + } + return row_count * src_pitch_in_block * block_size; + } +}; + +template +std::vector copy_texture_data(void *dst, const void *src, size_t widthInBlock, size_t heightInBlock, size_t depth, size_t mipmapCount) noexcept { std::vector Result; size_t offsetInDst = 0, offsetInSrc = 0; - size_t currentHeight = heightInBlock, currentWidth = widthInBlock; - size_t srcPitch = widthInBlock * blockSize; - for (unsigned mipLevel = 0; mipLevel < mipmapCount; mipLevel++) + // Every mipmap level of rsx textures use the same rowpitch. + size_t src_pitch = widthInBlock; + for (unsigned depth_level = 0; depth_level < depth; depth_level++) { - size_t rowPitch = align(currentWidth * blockSize, 256); + size_t miplevel_height_in_block = heightInBlock, miplevel_width_in_block = widthInBlock; + for (unsigned mip_level = 0; mip_level < mipmapCount; mip_level++) + { + size_t dst_pitch = align(miplevel_width_in_block * block_size_in_bytes, 256) / block_size_in_bytes; - MipmapLevelInfo currentMipmapLevelInfo = {}; - currentMipmapLevelInfo.offset = offsetInDst; - currentMipmapLevelInfo.height = currentHeight; - currentMipmapLevelInfo.width = currentWidth; - currentMipmapLevelInfo.rowPitch = rowPitch; - Result.push_back(currentMipmapLevelInfo); + MipmapLevelInfo currentMipmapLevelInfo = {}; + currentMipmapLevelInfo.offset = offsetInDst; + currentMipmapLevelInfo.height = miplevel_height_in_block * block_edge_in_texel; + currentMipmapLevelInfo.width = miplevel_width_in_block * block_edge_in_texel; + currentMipmapLevelInfo.rowPitch = dst_pitch * block_size_in_bytes; + Result.push_back(currentMipmapLevelInfo); - unsigned short *castedDst = (unsigned short *)dst, *castedSrc = (unsigned short *)src; - - for (unsigned row = 0; row < heightInBlock; row++) - for (int j = 0; j < currentWidth * 4; j++) - { - u16 tmp = castedSrc[offsetInSrc / 2 + row * srcPitch / 2 + j]; - castedDst[offsetInDst / 2 + row * rowPitch / 2 + j] = (tmp >> 8) | (tmp << 8); - } - - offsetInDst += currentHeight * rowPitch; - offsetInSrc += currentHeight * widthInBlock * blockSize; - currentHeight = MAX2(currentHeight / 2, 1); - currentWidth = MAX2(currentWidth / 2, 1); + offsetInSrc += T::template copy_mipmap_level((char*)dst + offsetInDst, (char*)src + offsetInSrc, miplevel_height_in_block, miplevel_width_in_block, dst_pitch, src_pitch); + offsetInDst += align(miplevel_height_in_block * dst_pitch * block_size_in_bytes, 512); + miplevel_height_in_block = MAX2(miplevel_height_in_block / 2, 1); + miplevel_width_in_block = MAX2(miplevel_width_in_block / 2, 1); + } } return Result; } @@ -328,12 +242,13 @@ size_t get_placed_texture_storage_size(const rsx::texture &texture, size_t rowPi size_t rowPitch = align(blockSizeInByte * widthInBlocks, rowPitchAlignement); - return rowPitch * heightInBlocks * 2; // * 2 for mipmap levels + return rowPitch * heightInBlocks * (texture.cubemap() ? 6 : 1) * 2; // * 2 for mipmap levels } std::vector upload_placed_texture(const rsx::texture &texture, size_t rowPitchAlignement, void* textureData) noexcept { size_t w = texture.width(), h = texture.height(); + size_t depth = texture.depth(); int format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); @@ -352,24 +267,28 @@ std::vector upload_placed_texture(const rsx::texture &texture, { case CELL_GCM_TEXTURE_A8R8G8B8: if (is_swizzled) - return writeTexelsSwizzled((char*)pixels, (char*)textureData, w, h, 4, texture.mipmap()); + return copy_texture_data(textureData, pixels, widthInBlocks, heightInBlocks, depth, texture.mipmap()); else - return writeTexelsGeneric((char*)pixels, (char*)textureData, w, h, 4, texture.mipmap()); + return copy_texture_data(textureData, pixels, widthInBlocks, heightInBlocks, depth, texture.mipmap()); case CELL_GCM_TEXTURE_A1R5G5B5: case CELL_GCM_TEXTURE_A4R4G4B4: case CELL_GCM_TEXTURE_R5G6B5: if (is_swizzled) - return write16bTexelsSwizzled((char*)pixels, (char*)textureData, w, h, 2, texture.mipmap()); + return copy_texture_data(textureData, pixels, widthInBlocks, heightInBlocks, depth, texture.mipmap()); else - return write16bTexelsGeneric((char*)pixels, (char*)textureData, w, h, 2, texture.mipmap()); + return copy_texture_data(textureData, pixels, widthInBlocks, heightInBlocks, depth, texture.mipmap()); case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: - return write16bX4TexelsGeneric((char*)pixels, (char*)textureData, w, h, 8, texture.mipmap()); + return copy_texture_data(textureData, pixels, widthInBlocks, heightInBlocks, depth, texture.mipmap()); case CELL_GCM_TEXTURE_COMPRESSED_DXT1: + return copy_texture_data(textureData, pixels, widthInBlocks, heightInBlocks, depth, texture.mipmap()); case CELL_GCM_TEXTURE_COMPRESSED_DXT23: + return copy_texture_data(textureData, pixels, widthInBlocks, heightInBlocks, depth, texture.mipmap()); case CELL_GCM_TEXTURE_COMPRESSED_DXT45: - return writeCompressedTexel((char*)pixels, (char*)textureData, widthInBlocks, blockEdge, heightInBlocks, blockEdge, blockSizeInByte, texture.mipmap()); + return copy_texture_data(textureData, pixels, widthInBlocks, heightInBlocks, depth, texture.mipmap()); + case CELL_GCM_TEXTURE_B8: + return copy_texture_data(textureData, pixels, widthInBlocks, heightInBlocks, depth, texture.mipmap()); default: - return writeTexelsGeneric((char*)pixels, (char*)textureData, w, h, blockSizeInByte, texture.mipmap()); + return copy_texture_data(textureData, pixels, widthInBlocks, heightInBlocks, depth, texture.mipmap()); } } From 6221fecf3bd584d1b036b2e9bd76ffd903192b5d Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Thu, 10 Dec 2015 02:52:27 +0100 Subject: [PATCH 04/13] common/d3d12/gl: Start implementing cubemap sampling --- rpcs3/Emu/RSX/CgBinaryProgram.h | 3 +- .../RSX/Common/FragmentProgramDecompiler.cpp | 41 ++++++++++++++++--- .../RSX/Common/FragmentProgramDecompiler.h | 3 +- rpcs3/Emu/RSX/Common/ShaderParam.h | 2 + rpcs3/Emu/RSX/Common/TextureUtils.cpp | 9 ++++ rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp | 4 ++ .../D3D12/D3D12FragmentProgramDecompiler.cpp | 28 +++++++++---- .../D3D12/D3D12FragmentProgramDecompiler.h | 2 +- rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp | 11 +++++ rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h | 4 +- rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp | 16 ++++++-- rpcs3/Emu/RSX/GL/GLCommonDecompiler.cpp | 4 ++ rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp | 4 +- rpcs3/Emu/RSX/GL/GLFragmentProgram.h | 7 ++-- rpcs3/Emu/RSX/GL/GLGSRender.cpp | 10 +++++ rpcs3/Emu/RSX/GL/GLProgramBuffer.h | 2 +- rpcs3/Emu/RSX/RSXFragmentProgram.h | 8 ++++ 17 files changed, 130 insertions(+), 28 deletions(-) diff --git a/rpcs3/Emu/RSX/CgBinaryProgram.h b/rpcs3/Emu/RSX/CgBinaryProgram.h index 80c2a92dd2..5d357e47dd 100644 --- a/rpcs3/Emu/RSX/CgBinaryProgram.h +++ b/rpcs3/Emu/RSX/CgBinaryProgram.h @@ -325,7 +325,8 @@ public: auto& vmfprog = vm::ps3::_ref(ptr + vmprog.program); u32 size; u32 ctrl = (vmfprog.outputFromH0 ? 0 : 0x40) | (vmfprog.depthReplace ? 0xe : 0); - GLFragmentDecompilerThread(m_glsl_shader, param_array, ptr + vmprog.ucode, size, ctrl).Task(); + std::vector td; + GLFragmentDecompilerThread(m_glsl_shader, param_array, ptr + vmprog.ucode, size, ctrl, td).Task(); vm::close(); } } diff --git a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp index 0831194f15..2f05e08db6 100644 --- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp @@ -5,12 +5,13 @@ #include "FragmentProgramDecompiler.h" -FragmentProgramDecompiler::FragmentProgramDecompiler(u32 addr, u32& size, u32 ctrl) : +FragmentProgramDecompiler::FragmentProgramDecompiler(u32 addr, u32& size, u32 ctrl, const std::vector &texture_dimensions) : m_addr(addr), m_size(size), m_const_index(0), m_location(0), - m_ctrl(ctrl) + m_ctrl(ctrl), + m_texture_dimensions(texture_dimensions) { m_size = 0; } @@ -128,7 +129,7 @@ std::string FragmentProgramDecompiler::AddConst() std::string FragmentProgramDecompiler::AddTex() { - return m_parr.AddParam(PF_PARAM_UNIFORM, "sampler2D", std::string("tex") + std::to_string(dst.tex_num)); + return m_parr.AddParam(PF_PARAM_UNIFORM, (m_texture_dimensions[dst.tex_num] == texture_dimension::texture_dimension_cubemap) ? "samplerCube" : "sampler2D", std::string("tex") + std::to_string(dst.tex_num)); } std::string FragmentProgramDecompiler::Format(const std::string& code) @@ -416,9 +417,39 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode) case RSX_FP_OPCODE_DDY: SetDst(getFunction(FUNCTION::FUNCTION_DFDY)); return true; case RSX_FP_OPCODE_NRM: SetDst("normalize($0)"); return true; case RSX_FP_OPCODE_BEM: LOG_ERROR(RSX, "Unimplemented TEX_SRB instruction: BEM"); return true; - case RSX_FP_OPCODE_TEX: SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE)); return true; + case RSX_FP_OPCODE_TEX: + if (dst.tex_num >= m_texture_dimensions.size()) + { + SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE)); + return true; + } + switch (m_texture_dimensions[dst.tex_num]) + { + case texture_dimension::texture_dimension_2d: + SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE)); + return true; + case texture_dimension::texture_dimension_cubemap: + SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE)); + return true; + } + return false; case RSX_FP_OPCODE_TEXBEM: SetDst("texture($t, $0.xy, $1.x)"); return true; - case RSX_FP_OPCODE_TXP: SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE_PROJ)); return true; //TODO: More testing (Sonic The Hedgehog (NPUB-30442/NPEB-00478) and The Simpsons Arcade Game (NPUB30563)) + case RSX_FP_OPCODE_TXP: + if (dst.tex_num >= m_texture_dimensions.size()) + { + SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE_PROJ)); + return true; + } + switch (m_texture_dimensions[dst.tex_num]) + { + case texture_dimension::texture_dimension_2d: + SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE_PROJ)); + return true; + case texture_dimension::texture_dimension_cubemap: + SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE_PROJ)); + return true; + } + return false; case RSX_FP_OPCODE_TXPBEM: SetDst("textureProj($t, $0.xyz, $1.x)"); return true; case RSX_FP_OPCODE_TXD: LOG_ERROR(RSX, "Unimplemented TEX_SRB instruction: TXD"); return true; case RSX_FP_OPCODE_TXB: SetDst("texture($t, $0.xy, $1.x)"); return true; diff --git a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.h b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.h index a6f5d9de73..6294db0e5f 100644 --- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.h +++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.h @@ -22,6 +22,7 @@ class FragmentProgramDecompiler std::string main; u32 m_addr; u32& m_size; + const std::vector m_texture_dimensions; u32 m_const_index; u32 m_offset; u32 m_location; @@ -107,6 +108,6 @@ protected: virtual void insertMainEnd(std::stringstream &OS) = 0; public: ParamArray m_parr; - FragmentProgramDecompiler(u32 addr, u32& size, u32 ctrl); + FragmentProgramDecompiler(u32 addr, u32& size, u32 ctrl, const std::vector &texture_dimensions); std::string Decompile(); }; diff --git a/rpcs3/Emu/RSX/Common/ShaderParam.h b/rpcs3/Emu/RSX/Common/ShaderParam.h index cfeb5c5911..69443dd6cb 100644 --- a/rpcs3/Emu/RSX/Common/ShaderParam.h +++ b/rpcs3/Emu/RSX/Common/ShaderParam.h @@ -15,6 +15,8 @@ enum class FUNCTION { FUNCTION_DFDY, FUNCTION_TEXTURE_SAMPLE, FUNCTION_TEXTURE_SAMPLE_PROJ, + FUNCTION_TEXTURE_CUBE_SAMPLE, + FUNCTION_TEXTURE_CUBE_SAMPLE_PROJ, }; enum class COMPARE { diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.cpp b/rpcs3/Emu/RSX/Common/TextureUtils.cpp index fae7e941d0..6ebdeba724 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.cpp +++ b/rpcs3/Emu/RSX/Common/TextureUtils.cpp @@ -115,6 +115,13 @@ struct texel_16bX4_format { } }; +/** + * Texture upload template. + * The template iterates over all depth (including cubemap) and over all mipmaps. + * The alignment is 256 for mipmap levels and 512 for depth (TODO: make this customisable for Vulkan ?) + * The template takes a struct with a "copy_mipmap_level" static function that copy the given mipmap level and returns the offset to add to the src buffer for next + * mipmap level (to allow same code for packed/non packed texels) + */ template std::vector copy_texture_data(void *dst, const void *src, size_t widthInBlock, size_t heightInBlock, size_t depth, size_t mipmapCount) noexcept { @@ -141,6 +148,7 @@ std::vector copy_texture_data(void *dst, const void *src, size_ miplevel_height_in_block = MAX2(miplevel_height_in_block / 2, 1); miplevel_width_in_block = MAX2(miplevel_width_in_block / 2, 1); } + offsetInSrc = align(offsetInSrc, 128); } return Result; } @@ -249,6 +257,7 @@ std::vector upload_placed_texture(const rsx::texture &texture, { size_t w = texture.width(), h = texture.height(); size_t depth = texture.depth(); + if (texture.cubemap()) depth *= 6; int format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp index 786c75ff9b..1c8f7e3c05 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp @@ -46,6 +46,10 @@ std::string getFunctionImp(FUNCTION f) return "$t.Sample($tsampler, $0.xy * $t_scale)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLE_PROJ: return "$t.Sample($tsampler, ($0.xy / $0.z) * $t_scale)"; + case FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE: + return "$t.Sample($tsampler, $0.xyz)"; + case FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE_PROJ: + return "$t.Sample($tsampler, ($0.xyz / $0.w))"; case FUNCTION::FUNCTION_DFDX: return "ddx($0)"; case FUNCTION::FUNCTION_DFDY: diff --git a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp index 8e5daf93ee..ddd83875d5 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp @@ -7,8 +7,8 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" -D3D12FragmentDecompiler::D3D12FragmentDecompiler(u32 addr, u32& size, u32 ctrl) : - FragmentProgramDecompiler(addr, size, ctrl) +D3D12FragmentDecompiler::D3D12FragmentDecompiler(u32 addr, u32& size, u32 ctrl, const std::vector &texture_dimensions) : + FragmentProgramDecompiler(addr, size, ctrl, texture_dimensions) { } @@ -110,7 +110,7 @@ void D3D12FragmentDecompiler::insertConstants(std::stringstream & OS) OS << "{" << std::endl; for (ParamType PT : m_parr.params[PF_PARAM_UNIFORM]) { - if (PT.type == "sampler2D") + if (PT.type == "sampler2D" || PT.type == "samplerCube") continue; for (ParamItem PI : PT.items) OS << " " << PT.type << " " << PI.name << ";" << std::endl; @@ -119,13 +119,23 @@ void D3D12FragmentDecompiler::insertConstants(std::stringstream & OS) for (ParamType PT : m_parr.params[PF_PARAM_UNIFORM]) { - if (PT.type != "sampler2D") - continue; - for (ParamItem PI : PT.items) + if (PT.type == "sampler2D") { - size_t textureIndex = atoi(PI.name.data() + 3); - OS << "Texture2D " << PI.name << " : register(t" << textureIndex << ");" << std::endl; - OS << "sampler " << PI.name << "sampler : register(s" << textureIndex << ");" << std::endl; + for (ParamItem PI : PT.items) + { + size_t textureIndex = atoi(PI.name.data() + 3); + OS << "Texture2D " << PI.name << " : register(t" << textureIndex << ");" << std::endl; + OS << "sampler " << PI.name << "sampler : register(s" << textureIndex << ");" << std::endl; + } + } + else if (PT.type == "samplerCube") + { + for (ParamItem PI : PT.items) + { + size_t textureIndex = atoi(PI.name.data() + 3); + OS << "TextureCube " << PI.name << " : register(t" << textureIndex << ");" << std::endl; + OS << "sampler " << PI.name << "sampler : register(s" << textureIndex << ");" << std::endl; + } } } } diff --git a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.h b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.h index bbba1ea8a7..29882f8126 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.h @@ -20,5 +20,5 @@ protected: virtual void insertMainStart(std::stringstream &OS) override; virtual void insertMainEnd(std::stringstream &OS) override; public: - D3D12FragmentDecompiler(u32 addr, u32& size, u32 ctrl); + D3D12FragmentDecompiler(u32 addr, u32& size, u32 ctrl, const std::vector &texture_dimensions); }; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp index 45f7e97928..89392c0b96 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp @@ -56,6 +56,17 @@ bool D3D12GSRender::load_program() fragment_program.offset = shader_program & ~0x3; fragment_program.addr = rsx::get_address(fragment_program.offset, (shader_program & 0x3) - 1); fragment_program.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL]; + fragment_program.texture_dimensions.clear(); + + for (u32 i = 0; i < rsx::limits::textures_count; ++i) + { + if (!textures[i].enabled()) + fragment_program.texture_dimensions.push_back(texture_dimension::texture_dimension_2d); + else if (textures[i].cubemap()) + fragment_program.texture_dimensions.push_back(texture_dimension::texture_dimension_cubemap); + else + fragment_program.texture_dimensions.push_back(texture_dimension::texture_dimension_2d); + } D3D12PipelineProperties prop = {}; prop.Topology = get_primitive_topology_type(draw_mode); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h index ecfe56aa92..39c5663984 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h @@ -147,7 +147,7 @@ struct D3D12Traits static void RecompileFragmentProgram(RSXFragmentProgram *RSXFP, FragmentProgramData& fragmentProgramData, size_t ID) { - D3D12FragmentDecompiler FS(RSXFP->addr, RSXFP->size, RSXFP->ctrl); + D3D12FragmentDecompiler FS(RSXFP->addr, RSXFP->size, RSXFP->ctrl, RSXFP->texture_dimensions); const std::string &shader = FS.Decompile(); fragmentProgramData.Compile(shader, Shader::SHADER_TYPE::SHADER_TYPE_FRAGMENT); fragmentProgramData.m_textureCount = 0; @@ -155,7 +155,7 @@ struct D3D12Traits { for (const ParamItem PI : PT.items) { - if (PT.type == "sampler2D") + if (PT.type == "sampler2D" || PT.type == "samplerCube") { size_t texture_unit = atoi(PI.name.c_str() + 3); fragmentProgramData.m_textureCount = std::max(texture_unit + 1, fragmentProgramData.m_textureCount); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp index ab3d4c1ec9..09330ae770 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp @@ -52,6 +52,8 @@ ComPtr upload_single_texture( data_heap &texture_buffer_heap) { size_t w = texture.width(), h = texture.height(); + size_t depth = texture.depth(); + if (texture.cubemap()) depth *= 6; int format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); DXGI_FORMAT dxgi_format = get_texture_format(format); @@ -70,7 +72,7 @@ ComPtr upload_single_texture( ThrowIfFailed(device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC::Tex2D(dxgi_format, (UINT)w, (UINT)h, 1, texture.mipmap()), + &CD3DX12_RESOURCE_DESC::Tex2D(dxgi_format, (UINT)w, (UINT)h, depth, texture.mipmap()), D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(result.GetAddressOf()) @@ -174,9 +176,17 @@ void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_ } D3D12_SHADER_RESOURCE_VIEW_DESC shared_resource_view_desc = {}; - shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + if (textures[i].cubemap()) + { + shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE; + shared_resource_view_desc.TextureCube.MipLevels = textures[i].mipmap(); + } + else + { + shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + shared_resource_view_desc.Texture2D.MipLevels = textures[i].mipmap(); + } shared_resource_view_desc.Format = get_texture_format(format); - shared_resource_view_desc.Texture2D.MipLevels = textures[i].mipmap(); switch (format) { diff --git a/rpcs3/Emu/RSX/GL/GLCommonDecompiler.cpp b/rpcs3/Emu/RSX/GL/GLCommonDecompiler.cpp index c4fb1c0d1d..afa7be3b7c 100644 --- a/rpcs3/Emu/RSX/GL/GLCommonDecompiler.cpp +++ b/rpcs3/Emu/RSX/GL/GLCommonDecompiler.cpp @@ -44,6 +44,10 @@ std::string getFunctionImpl(FUNCTION f) return "texture($t, $0.xy)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLE_PROJ: return "textureProj($t, $0.xyz, $1.x)"; // Note: $1.x is bias + case FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE: + return "texture($t, $0.xyz)"; + case FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE_PROJ: + return "textureProj($t, $0.xyzw, $1.x)"; // Note: $1.x is bias case FUNCTION::FUNCTION_DFDX: return "dFdx($0)"; case FUNCTION::FUNCTION_DFDY: diff --git a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp index 2bf09ea511..4e7afca038 100644 --- a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp @@ -156,9 +156,9 @@ GLFragmentProgram::~GLFragmentProgram() // } //} -void GLFragmentProgram::Decompile(RSXFragmentProgram& prog) +void GLFragmentProgram::Decompile(RSXFragmentProgram& prog, const std::vector &td) { - GLFragmentDecompilerThread decompiler(shader, parr, prog.addr, prog.size, prog.ctrl); + GLFragmentDecompilerThread decompiler(shader, parr, prog.addr, prog.size, prog.ctrl, td); decompiler.Task(); for (const ParamType& PT : decompiler.m_parr.params[PF_PARAM_UNIFORM]) { diff --git a/rpcs3/Emu/RSX/GL/GLFragmentProgram.h b/rpcs3/Emu/RSX/GL/GLFragmentProgram.h index ad20788ea5..4a1f07c03d 100644 --- a/rpcs3/Emu/RSX/GL/GLFragmentProgram.h +++ b/rpcs3/Emu/RSX/GL/GLFragmentProgram.h @@ -9,8 +9,8 @@ struct GLFragmentDecompilerThread : public FragmentProgramDecompiler std::string& m_shader; ParamArray& m_parrDummy; public: - GLFragmentDecompilerThread(std::string& shader, ParamArray& parr, u32 addr, u32& size, u32 ctrl) - : FragmentProgramDecompiler(addr, size, ctrl) + GLFragmentDecompilerThread(std::string& shader, ParamArray& parr, u32 addr, u32& size, u32 ctrl, const std::vector &texture_dimensions) + : FragmentProgramDecompiler(addr, size, ctrl, texture_dimensions) , m_shader(shader) , m_parrDummy(parr) { @@ -49,8 +49,9 @@ public: /** * Decompile a fragment shader located in the PS3's Memory. This function operates synchronously. * @param prog RSXShaderProgram specifying the location and size of the shader in memory + * @param td texture dimensions of input textures */ - void Decompile(RSXFragmentProgram& prog); + void Decompile(RSXFragmentProgram& prog, const std::vector &td); /** Compile the decompiled fragment shader into a format we can use with OpenGL. */ void Compile(); diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index e4c9b1f8b9..df978c95d7 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -1231,6 +1231,16 @@ bool GLGSRender::load_program() fragment_program.addr = rsx::get_address(fragment_program.offset, (shader_program & 0x3) - 1); fragment_program.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL]; + for (u32 i = 0; i < rsx::limits::textures_count; ++i) + { + if (!textures[i].enabled()) + fragment_program.texture_dimensions.push_back(texture_dimension::texture_dimension_2d); + else if (textures[i].cubemap()) + fragment_program.texture_dimensions.push_back(texture_dimension::texture_dimension_cubemap); + else + fragment_program.texture_dimensions.push_back(texture_dimension::texture_dimension_2d); + } + __glcheck m_program = m_prog_buffer.getGraphicPipelineState(&vertex_program, &fragment_program, nullptr, nullptr); __glcheck m_program->use(); diff --git a/rpcs3/Emu/RSX/GL/GLProgramBuffer.h b/rpcs3/Emu/RSX/GL/GLProgramBuffer.h index 28652bf975..39df0b9fd6 100644 --- a/rpcs3/Emu/RSX/GL/GLProgramBuffer.h +++ b/rpcs3/Emu/RSX/GL/GLProgramBuffer.h @@ -14,7 +14,7 @@ struct GLTraits static void RecompileFragmentProgram(RSXFragmentProgram *RSXFP, FragmentProgramData& fragmentProgramData, size_t ID) { - fragmentProgramData.Decompile(*RSXFP); + fragmentProgramData.Decompile(*RSXFP, RSXFP->texture_dimensions); fragmentProgramData.Compile(); //checkForGlError("m_fragment_prog.Compile"); diff --git a/rpcs3/Emu/RSX/RSXFragmentProgram.h b/rpcs3/Emu/RSX/RSXFragmentProgram.h index ac2f8a69e9..1bde687d92 100644 --- a/rpcs3/Emu/RSX/RSXFragmentProgram.h +++ b/rpcs3/Emu/RSX/RSXFragmentProgram.h @@ -204,12 +204,20 @@ static const std::string rsx_fp_op_names[] = "NULL", "BRK", "CAL", "IFE", "LOOP", "REP", "RET" }; +enum class texture_dimension +{ + texture_dimension_2d, + texture_dimension_2d_array, + texture_dimension_cubemap, +}; + struct RSXFragmentProgram { u32 size; u32 addr; u32 offset; u32 ctrl; + std::vector texture_dimensions; RSXFragmentProgram() : size(0) From 1cda2977bb79e85aa232bb318f06d0977fc3c8b8 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Tue, 8 Dec 2015 23:42:06 +0100 Subject: [PATCH 05/13] common/d3d12: emulate polygon mode --- rpcs3/Emu/RSX/Common/BufferUtils.cpp | 9 ++++++++- rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp | 13 +++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/BufferUtils.cpp b/rpcs3/Emu/RSX/Common/BufferUtils.cpp index dd91475a5b..b5eda28331 100644 --- a/rpcs3/Emu/RSX/Common/BufferUtils.cpp +++ b/rpcs3/Emu/RSX/Common/BufferUtils.cpp @@ -180,14 +180,19 @@ bool is_primitive_native(unsigned m_draw_mode) noexcept case CELL_GCM_PRIMITIVE_TRIANGLES: case CELL_GCM_PRIMITIVE_TRIANGLE_STRIP: case CELL_GCM_PRIMITIVE_QUAD_STRIP: - case CELL_GCM_PRIMITIVE_POLYGON: return true; + case CELL_GCM_PRIMITIVE_POLYGON: case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: case CELL_GCM_PRIMITIVE_QUADS: return false; } } +/** We assume that polygon is convex in polygon mode (constraints in OpenGL) + *In such case polygon triangulation equates to triangle fan with arbitrary start vertex + * see http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/polygon-triangulation-r3334 + */ + size_t get_index_count(unsigned m_draw_mode, unsigned initial_index_count) noexcept { // Index count @@ -196,6 +201,7 @@ size_t get_index_count(unsigned m_draw_mode, unsigned initial_index_count) noexc switch (m_draw_mode) { + case CELL_GCM_PRIMITIVE_POLYGON: case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: return (initial_index_count - 2) * 3; case CELL_GCM_PRIMITIVE_QUADS: @@ -221,6 +227,7 @@ void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst, switch (draw_mode) { case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: + case CELL_GCM_PRIMITIVE_POLYGON: for (unsigned i = 0; i < (count - 2); i++) { typedDst[3 * i] = first; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp index 4f4ed5eec1..81fddab646 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp @@ -301,10 +301,10 @@ D3D12_PRIMITIVE_TOPOLOGY get_primitive_topology(u8 draw_mode) noexcept case CELL_GCM_PRIMITIVE_TRIANGLE_STRIP: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; // Emulated case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: - case CELL_GCM_PRIMITIVE_QUADS: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - - case CELL_GCM_PRIMITIVE_QUAD_STRIP: + case CELL_GCM_PRIMITIVE_QUADS: case CELL_GCM_PRIMITIVE_POLYGON: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + + case CELL_GCM_PRIMITIVE_QUAD_STRIP: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; } unreachable("Wrong draw mode"); } @@ -318,11 +318,12 @@ D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(u8 draw_mode) noexcept case CELL_GCM_PRIMITIVE_LINE_STRIP: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE; case CELL_GCM_PRIMITIVE_TRIANGLES: case CELL_GCM_PRIMITIVE_TRIANGLE_STRIP: - case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - case CELL_GCM_PRIMITIVE_QUADS: + case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: + case CELL_GCM_PRIMITIVE_POLYGON: + case CELL_GCM_PRIMITIVE_QUADS: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; // unsupported case CELL_GCM_PRIMITIVE_QUAD_STRIP: - case CELL_GCM_PRIMITIVE_POLYGON: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; } unreachable("Wrong draw mode"); } From fcf775100845080974a3922b6051ff68d47e5417 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 12 Dec 2015 18:53:00 +0100 Subject: [PATCH 06/13] d3d12: Fix handling of disabled texture Fix After Burner Climax textures. --- rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp | 9 ++++- rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp | 59 +++++++++++++++------------- 2 files changed, 38 insertions(+), 30 deletions(-) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp index bb02d2783c..6d0002db3a 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp @@ -159,9 +159,14 @@ void D3D12GSRender::upload_and_bind_scale_offset_matrix(size_t descriptorIndex) size_t tex_idx = 0; for (u32 i = 0; i < rsx::limits::textures_count; ++i) { - if (!textures[i].enabled()) continue; + if (!textures[i].enabled()) + { + int is_unorm = false; + memcpy((char*)mapped_buffer + heap_offset + (18 + tex_idx++) * sizeof(int), &is_unorm, sizeof(int)); + continue; + } size_t w = textures[i].width(), h = textures[i].height(); - if (!w || !h) continue; +// if (!w || !h) continue; int is_unorm = (textures[i].format() & CELL_GCM_TEXTURE_UN); memcpy((char*)mapped_buffer + heap_offset + (18 + tex_idx++) * sizeof(int), &is_unorm, sizeof(int)); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp index 09330ae770..397141154f 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp @@ -133,9 +133,38 @@ void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_ for (u32 i = 0; i < rsx::limits::textures_count; ++i) { - if (!textures[i].enabled()) continue; + if (!textures[i].enabled()) + { + // Now fill remaining texture slots with dummy texture/sampler + + D3D12_SHADER_RESOURCE_VIEW_DESC shader_resource_view_desc = {}; + shader_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + shader_resource_view_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + shader_resource_view_desc.Texture2D.MipLevels = 1; + shader_resource_view_desc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING( + D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0, + D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0, + D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0, + D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0); + m_device->CreateShaderResourceView(m_dummy_texture, &shader_resource_view_desc, + CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetCPUDescriptorHandleForHeapStart()) + .Offset((INT)descriptor_index + (INT)used_texture, g_descriptor_stride_srv_cbv_uav) + ); + + D3D12_SAMPLER_DESC sampler_desc = {}; + sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; + sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + m_device->CreateSampler(&sampler_desc, + CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().sampler_descriptor_heap[get_current_resource_storage().sampler_descriptors_heap_index]->GetCPUDescriptorHandleForHeapStart()) + .Offset((INT)get_current_resource_storage().current_sampler_index + (INT)used_texture, g_descriptor_stride_samplers) + ); + used_texture++; + continue; + } size_t w = textures[i].width(), h = textures[i].height(); - if (!w || !h) continue; +// if (!w || !h) continue; const u32 texaddr = rsx::get_address(textures[i].offset(), textures[i].location()); @@ -332,32 +361,6 @@ void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_ used_texture++; } - // Now fill remaining texture slots with dummy texture/sampler - for (; used_texture < texture_count; used_texture++) - { - D3D12_SHADER_RESOURCE_VIEW_DESC shader_resource_view_desc = {}; - shader_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; - shader_resource_view_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - shader_resource_view_desc.Texture2D.MipLevels = 1; - shader_resource_view_desc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING( - D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0, - D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0, - D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0, - D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0); - m_device->CreateShaderResourceView(m_dummy_texture, &shader_resource_view_desc, - CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetCPUDescriptorHandleForHeapStart()) - .Offset((INT)descriptor_index + (INT)used_texture, g_descriptor_stride_srv_cbv_uav) - ); - D3D12_SAMPLER_DESC sampler_desc = {}; - sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; - sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - m_device->CreateSampler(&sampler_desc, - CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().sampler_descriptor_heap[get_current_resource_storage().sampler_descriptors_heap_index]->GetCPUDescriptorHandleForHeapStart()) - .Offset((INT)get_current_resource_storage().current_sampler_index + (INT)used_texture, g_descriptor_stride_samplers) - ); - } } #endif From 27807f3a618fd02f81007838427dd857fdef1a50 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Mon, 30 Nov 2015 20:16:24 +0100 Subject: [PATCH 07/13] d3d12: D8R8G8B8 and A8R8G8B8 are essentially the same. --- rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp index 397141154f..bea41ccce2 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp @@ -239,6 +239,7 @@ void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_ shared_resource_view_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; break; case CELL_GCM_TEXTURE_A8R8G8B8: + case CELL_GCM_TEXTURE_D8R8G8B8: { @@ -312,28 +313,6 @@ void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_ case CELL_GCM_TEXTURE_D1R5G5B5: shared_resource_view_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; break; - case CELL_GCM_TEXTURE_D8R8G8B8: - { - const int RemapValue[4] = - { - 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_FORCE_VALUE_1 - }; - - u8 remap_a = textures[i].remap() & 0x3; - u8 remap_r = (textures[i].remap() >> 2) & 0x3; - u8 remap_g = (textures[i].remap() >> 4) & 0x3; - u8 remap_b = (textures[i].remap() >> 6) & 0x3; - - shared_resource_view_desc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING( - RemapValue[remap_a], - RemapValue[remap_r], - RemapValue[remap_g], - RemapValue[remap_b]); - break; - } case CELL_GCM_TEXTURE_Y16_X16_FLOAT: shared_resource_view_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; break; From d7b4b2fd49eb9d8ae041410abee423a47d9be7c6 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Tue, 8 Dec 2015 00:35:22 +0100 Subject: [PATCH 08/13] d3d12: Support surface format R5G6B5 --- rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp | 2 +- rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp index 81fddab646..6b2bf3bb05 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp @@ -332,7 +332,7 @@ DXGI_FORMAT get_color_surface_format(u8 format) noexcept { switch (format) { - case CELL_GCM_SURFACE_R5G6B5: return DXGI_FORMAT_R8G8B8A8_UNORM; + case CELL_GCM_SURFACE_R5G6B5: return DXGI_FORMAT_B5G6R5_UNORM; case CELL_GCM_SURFACE_A8R8G8B8: return DXGI_FORMAT_R8G8B8A8_UNORM; case CELL_GCM_SURFACE_F_W16Z16Y16X16: return DXGI_FORMAT_R16G16B16A16_FLOAT; case CELL_GCM_SURFACE_F_X32: return DXGI_FORMAT_R32_FLOAT; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp index fdea7f00d4..68b7a19019 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp @@ -375,6 +375,9 @@ namespace size_t row_pitch; switch (color_surface_format) { + case CELL_GCM_SURFACE_R5G6B5: + row_pitch = align(clip_w * 2, 256); + break; case CELL_GCM_SURFACE_A8R8G8B8: row_pitch = align(clip_w * 4, 256); break; @@ -571,6 +574,10 @@ void D3D12GSRender::copy_render_target_to_dma_location() size_t srcPitch, dstPitch; switch (m_surface.color_format) { + case CELL_GCM_SURFACE_R5G6B5: + srcPitch = align(clip_w * 2, 256); + dstPitch = clip_w * 2; + break; case CELL_GCM_SURFACE_A8R8G8B8: srcPitch = align(clip_w * 4, 256); dstPitch = clip_w * 4; @@ -617,6 +624,10 @@ void D3D12GSRender::copy_render_targets_to_memory(void *buffer, u8 rtt) size_t srcPitch, dstPitch; switch (m_surface.color_format) { + case CELL_GCM_SURFACE_R5G6B5: + srcPitch = align(clip_w * 2, 256); + dstPitch = clip_w * 2; + break; case CELL_GCM_SURFACE_A8R8G8B8: srcPitch = align(clip_w * 4, 256); dstPitch = clip_w * 4; From 456f83671a305b038c8f7d0720d6b07642a9b7fb Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 13 Dec 2015 20:56:50 +0100 Subject: [PATCH 09/13] d3d12: Add formatting abilities to unreachable macro --- rpcs3/Emu/RSX/D3D12/D3D12Utils.cpp | 4 ++-- rpcs3/Emu/RSX/D3D12/D3D12Utils.h | 13 ++++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Utils.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Utils.cpp index 6c77a9b8ca..73afe3c9d2 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Utils.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Utils.cpp @@ -262,9 +262,9 @@ void D3D12GSRender::initConvertShader() p.second->Release(); } -void unreachable_internal(const char *msg, const char *file, unsigned line) + +void unreachable_internal() { - LOG_ERROR(RSX, "file %s line %d : %s", file, line, msg); abort(); #ifdef LLVM_BUILTIN_UNREACHABLE LLVM_BUILTIN_UNREACHABLE; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Utils.h b/rpcs3/Emu/RSX/D3D12/D3D12Utils.h index e4cf19b432..d1d1315c58 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Utils.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12Utils.h @@ -45,7 +45,14 @@ # define LLVM_BUILTIN_UNREACHABLE __assume(false) #endif -LLVM_ATTRIBUTE_NORETURN void unreachable_internal(const char *msg = nullptr, const char *file = nullptr, unsigned line = 0); +LLVM_ATTRIBUTE_NORETURN void unreachable_internal(); + +template +void unreachable_internal_verbose(const char *file, unsigned line, const Args &...args) +{ + LOG_ERROR(RSX, "file %s line %d : %s", file, line, fmt::format(args...)); + unreachable_internal(); +} /// Marks that the current location is not supposed to be reachable. /// In !NDEBUG builds, prints the message and location info to stderr. @@ -56,8 +63,8 @@ LLVM_ATTRIBUTE_NORETURN void unreachable_internal(const char *msg = nullptr, con /// Use this instead of assert(0). It conveys intent more clearly and /// allows compilers to omit some unnecessary code. #ifndef NDEBUG -#define unreachable(msg) \ - unreachable_internal(msg, __FILE__, __LINE__) +#define unreachable(...) \ + unreachable_internal_verbose(__FILE__, __LINE__, ##__VA_ARGS__) //#elif defined(LLVM_BUILTIN_UNREACHABLE) //#define unreachable(msg) LLVM_BUILTIN_UNREACHABLE #else From 81f05daff2919650d70649f36938c0b25f1b876e Mon Sep 17 00:00:00 2001 From: Zangetsu38 Date: Sun, 29 Nov 2015 17:31:02 +0100 Subject: [PATCH 10/13] d3d12: Add more log callback for support dev --- rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp | 92 +++++++++++++--------------- 1 file changed, 44 insertions(+), 48 deletions(-) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp index 6b2bf3bb05..97300be2c9 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp @@ -18,9 +18,9 @@ D3D12_BLEND_OP get_blend_op(u16 op) noexcept case CELL_GCM_FUNC_ADD_SIGNED: case CELL_GCM_FUNC_REVERSE_ADD_SIGNED: case CELL_GCM_FUNC_REVERSE_SUBTRACT_SIGNED: - unreachable("Unsupported blend op"); + unreachable("Unsupported blend op used %x, please report this to a developer.", op); } - unreachable("Wrong blend op"); + unreachable("Unimplemented blend op used %x, please report this to a developer.", op); } D3D12_BLEND get_blend_factor(u16 factor) noexcept @@ -42,9 +42,9 @@ D3D12_BLEND get_blend_factor(u16 factor) noexcept case CELL_GCM_ONE_MINUS_CONSTANT_COLOR: case CELL_GCM_CONSTANT_ALPHA: case CELL_GCM_ONE_MINUS_CONSTANT_ALPHA: - unreachable("Unsupported blend color factor"); + unreachable("Unsupported blend color factor used %x, please report this to a developer.", factor); } - unreachable("Wrong blend color factor"); + unreachable("Unimplemented blend color factor used %x, please report this to a developer.", factor); } D3D12_BLEND get_blend_factor_alpha(u16 factor) noexcept @@ -66,9 +66,9 @@ D3D12_BLEND get_blend_factor_alpha(u16 factor) noexcept case CELL_GCM_ONE_MINUS_CONSTANT_COLOR: case CELL_GCM_CONSTANT_ALPHA: case CELL_GCM_ONE_MINUS_CONSTANT_ALPHA: - unreachable("Unsupported blend alpha factor"); + unreachable("Unsupported blend alpha factor used %x, please report this to a developer.", factor); } - unreachable("Wrong blend alpha factor"); + unreachable("Unimplemented blend alpha factor used %x, please report this to a developer.", factor); } /** @@ -94,7 +94,7 @@ D3D12_LOGIC_OP get_logic_op(u32 op) noexcept case CELL_GCM_OR_INVERTED: return D3D12_LOGIC_OP_OR_INVERTED; case CELL_GCM_NAND: return D3D12_LOGIC_OP_NAND; } - unreachable("Wrong logic op"); + unreachable("Unimplemented logic op used %x, please report this to a developer.", op); } /** @@ -113,15 +113,13 @@ D3D12_STENCIL_OP get_stencil_op(u32 op) noexcept case CELL_GCM_INCR_WRAP: return D3D12_STENCIL_OP_INCR; case CELL_GCM_DECR_WRAP: return D3D12_STENCIL_OP_DECR; } - LOG_ERROR(RSX, "Unknow stencil op used %x, please report this to a developer.", op); - unreachable("Wrong Stencil op"); + unreachable("Unimplemented stencil op used %x, please report this to a developer.", op); } D3D12_COMPARISON_FUNC get_compare_func(u32 op) noexcept { switch (op) { - case CELL_GCM_ZERO: case CELL_GCM_NEVER: return D3D12_COMPARISON_FUNC_NEVER; case CELL_GCM_LESS: return D3D12_COMPARISON_FUNC_LESS; case CELL_GCM_EQUAL: return D3D12_COMPARISON_FUNC_EQUAL; @@ -130,8 +128,10 @@ D3D12_COMPARISON_FUNC get_compare_func(u32 op) noexcept case CELL_GCM_NOTEQUAL: return D3D12_COMPARISON_FUNC_NOT_EQUAL; case CELL_GCM_GEQUAL: return D3D12_COMPARISON_FUNC_GREATER_EQUAL; case CELL_GCM_ALWAYS: return D3D12_COMPARISON_FUNC_ALWAYS; + case CELL_GCM_ZERO: + unreachable("Unsupported compare function used %x, please report this to a developer.", op); } - unreachable("Wrong compare function"); + unreachable("Unimplemented compare function used %x, please report this to a developer.", op); } DXGI_FORMAT get_texture_format(int format) noexcept @@ -157,7 +157,7 @@ DXGI_FORMAT get_texture_format(int format) noexcept case CELL_GCM_TEXTURE_G8B8: return DXGI_FORMAT_G8R8_G8B8_UNORM; case CELL_GCM_TEXTURE_R6G5B5: - // Not native + /*Not native*/ return DXGI_FORMAT_R8G8B8A8_UNORM; case CELL_GCM_TEXTURE_DEPTH24_D8: return DXGI_FORMAT_R32_UINT; @@ -192,9 +192,9 @@ DXGI_FORMAT get_texture_format(int format) noexcept case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: - unreachable( "Unimplemented Texture format"); + unreachable("Unsupported texture format used %x, please report this to a developer.", format); } - unreachable("Wrong Texture format"); + unreachable("Unimplemented texture format used %x, please report this to a developer.", format); } UINT get_texture_max_aniso(u8 aniso) noexcept @@ -210,7 +210,7 @@ UINT get_texture_max_aniso(u8 aniso) noexcept case CELL_GCM_TEXTURE_MAX_ANISO_12: return 12; case CELL_GCM_TEXTURE_MAX_ANISO_16: return 16; } - unreachable("Wrong Texture max aniso"); + unreachable("Unimplemented texture max aniso used %x, please report this to a developer.", aniso); } D3D12_TEXTURE_ADDRESS_MODE get_texture_wrap_mode(u8 wrap) noexcept @@ -226,7 +226,7 @@ D3D12_TEXTURE_ADDRESS_MODE get_texture_wrap_mode(u8 wrap) noexcept case CELL_GCM_TEXTURE_MIRROR_ONCE_BORDER: return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE; case CELL_GCM_TEXTURE_MIRROR_ONCE_CLAMP: return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE; } - unreachable("Wrong texture wrap mode"); + unreachable("Unimplemented texture wrap mode used %x, please report this to a developer.", wrap); } namespace @@ -260,12 +260,11 @@ namespace mip = D3D12_FILTER_TYPE_LINEAR; return; case CELL_GCM_TEXTURE_CONVOLUTION_MIN: - LOG_WARNING(RSX, "CELL_GCM_TEXTURE_CONVOLUTION_MIN not supported, fallback to bilinear filtering"); min = D3D12_FILTER_TYPE_LINEAR; mip = D3D12_FILTER_TYPE_POINT; return; } - unreachable("Wrong min filter"); + unreachable("Unimplemented min filter used %x, please report this to a developer.", min_filter); } D3D12_FILTER_TYPE get_mag_filter(u8 mag_filter) noexcept @@ -275,9 +274,7 @@ namespace case CELL_GCM_TEXTURE_NEAREST: return D3D12_FILTER_TYPE_POINT; case CELL_GCM_TEXTURE_LINEAR: return D3D12_FILTER_TYPE_LINEAR; } - // Catherine uses this - LOG_WARNING(RSX, "Unknow mag filter used %x, fallback to bilinear filtering", mag_filter); - return D3D12_FILTER_TYPE_LINEAR; + unreachable("Unimplemented mag filter used %x, please report this to a developer.", mag_filter); } } @@ -299,33 +296,32 @@ D3D12_PRIMITIVE_TOPOLOGY get_primitive_topology(u8 draw_mode) noexcept case CELL_GCM_PRIMITIVE_LINE_STRIP: return D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; case CELL_GCM_PRIMITIVE_TRIANGLES: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; case CELL_GCM_PRIMITIVE_TRIANGLE_STRIP: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; - // Emulated + case CELL_GCM_PRIMITIVE_QUAD_STRIP: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + case CELL_GCM_PRIMITIVE_POLYGON: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: case CELL_GCM_PRIMITIVE_QUADS: - case CELL_GCM_PRIMITIVE_POLYGON: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - - case CELL_GCM_PRIMITIVE_QUAD_STRIP: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + unreachable("Unsupported draw mode used %x, please report this to a developer.", draw_mode); } - unreachable("Wrong draw mode"); + unreachable("Unimplemented draw mode used %x, please report this to a developer.", draw_mode); } + D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(u8 draw_mode) noexcept { switch (draw_mode) { case CELL_GCM_PRIMITIVE_POINTS: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT; + case CELL_GCM_PRIMITIVE_LINE_STRIP: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE; + case CELL_GCM_PRIMITIVE_TRIANGLES: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + case CELL_GCM_PRIMITIVE_QUADS: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + case CELL_GCM_PRIMITIVE_QUAD_STRIP: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; case CELL_GCM_PRIMITIVE_LINES: case CELL_GCM_PRIMITIVE_LINE_LOOP: - case CELL_GCM_PRIMITIVE_LINE_STRIP: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE; - case CELL_GCM_PRIMITIVE_TRIANGLES: case CELL_GCM_PRIMITIVE_TRIANGLE_STRIP: case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: case CELL_GCM_PRIMITIVE_POLYGON: - case CELL_GCM_PRIMITIVE_QUADS: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - // unsupported - case CELL_GCM_PRIMITIVE_QUAD_STRIP: - return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + unreachable("Unsupported draw mode used %x, please report this to a developer.", draw_mode); } - unreachable("Wrong draw mode"); + unreachable("Unimplemented draw mode used %x, please report this to a developer.", draw_mode); } DXGI_FORMAT get_color_surface_format(u8 format) noexcept @@ -337,7 +333,7 @@ DXGI_FORMAT get_color_surface_format(u8 format) noexcept case CELL_GCM_SURFACE_F_W16Z16Y16X16: return DXGI_FORMAT_R16G16B16A16_FLOAT; case CELL_GCM_SURFACE_F_X32: return DXGI_FORMAT_R32_FLOAT; } - unreachable("Wrong color surface format"); + unreachable("Unimplemented color surface format used %x, please report this to a developer.", format); } DXGI_FORMAT get_depth_stencil_surface_format(u8 format) noexcept @@ -347,7 +343,7 @@ DXGI_FORMAT get_depth_stencil_surface_format(u8 format) noexcept case CELL_GCM_SURFACE_Z16: return DXGI_FORMAT_D16_UNORM; case CELL_GCM_SURFACE_Z24S8: return DXGI_FORMAT_D24_UNORM_S8_UINT; } - unreachable("Wrong depth stencil surface format"); + unreachable("Unimplemented depth stencil surface format used %x, please report this to a developer.", format); } DXGI_FORMAT get_depth_stencil_surface_clear_format(u8 format) noexcept @@ -357,7 +353,7 @@ DXGI_FORMAT get_depth_stencil_surface_clear_format(u8 format) noexcept case CELL_GCM_SURFACE_Z16: return DXGI_FORMAT_D16_UNORM; case CELL_GCM_SURFACE_Z24S8: return DXGI_FORMAT_D24_UNORM_S8_UINT; } - unreachable("Wrong depth stencil surface format"); + unreachable("Unimplemented depth stencil surface format used %x, please report this to a developer.", format); } DXGI_FORMAT get_depth_stencil_typeless_surface_format(u8 format) noexcept @@ -367,7 +363,7 @@ DXGI_FORMAT get_depth_stencil_typeless_surface_format(u8 format) noexcept case CELL_GCM_SURFACE_Z16: return DXGI_FORMAT_R16_TYPELESS; case CELL_GCM_SURFACE_Z24S8: return DXGI_FORMAT_R24G8_TYPELESS; } - unreachable("Wrong depth stencil surface format"); + unreachable("Unimplemented depth stencil surface format used %x, please report this to a developer.", format); } DXGI_FORMAT get_depth_samplable_surface_format(u8 format) noexcept @@ -377,7 +373,7 @@ DXGI_FORMAT get_depth_samplable_surface_format(u8 format) noexcept case CELL_GCM_SURFACE_Z16: return DXGI_FORMAT_R16_FLOAT; case CELL_GCM_SURFACE_Z24S8: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; } - unreachable("Wrong depth stencil surface format"); + unreachable("Unimplemented depth stencil surface format used %x, please report this to a developer.", format); } BOOL get_front_face_ccw(u32 set_front_face_value) noexcept @@ -388,7 +384,7 @@ BOOL get_front_face_ccw(u32 set_front_face_value) noexcept case CELL_GCM_CW: return FALSE; case CELL_GCM_CCW: return TRUE; } - unreachable("Wrong front face value"); + unreachable("Unimplemented front face value used %x, please report this to a developer.", set_front_face_value); } DXGI_FORMAT get_index_type(u8 index_type) noexcept @@ -398,7 +394,7 @@ DXGI_FORMAT get_index_type(u8 index_type) noexcept case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: return DXGI_FORMAT_R16_UINT; case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: return DXGI_FORMAT_R32_UINT; } - unreachable("Wrong index type"); + unreachable("Unimplemented index type used %x, please report this to a developer.", index_type); } DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept @@ -414,7 +410,7 @@ DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept case 3: return DXGI_FORMAT_R16G16B16A16_SNORM; // No 3 channel type case 4: return DXGI_FORMAT_R16G16B16A16_SNORM; } - unreachable("Wrong type size"); + unreachable("Unimplemented type size used %x, please report this to a developer.", size); } case CELL_GCM_VERTEX_F: { @@ -425,7 +421,7 @@ DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept case 3: return DXGI_FORMAT_R32G32B32_FLOAT; case 4: return DXGI_FORMAT_R32G32B32A32_FLOAT; } - unreachable("Wrong type size"); + unreachable("Unimplemented type size used %x, please report this to a developer.", size); } case CELL_GCM_VERTEX_SF: { @@ -436,7 +432,7 @@ DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept case 3: return DXGI_FORMAT_R16G16B16A16_FLOAT; // No 3 channel type case 4: return DXGI_FORMAT_R16G16B16A16_FLOAT; } - unreachable("Wrong type size"); + unreachable("Unimplemented type size used %x, please report this to a developer.", size); } case CELL_GCM_VERTEX_UB: { @@ -447,7 +443,7 @@ DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept case 3: return DXGI_FORMAT_R8G8B8A8_UNORM; // No 3 channel type case 4: return DXGI_FORMAT_R8G8B8A8_UNORM; } - unreachable("Wrong type size"); + unreachable("Unimplemented type size used %x, please report this to a developer.", size); } case CELL_GCM_VERTEX_S32K: { @@ -458,7 +454,7 @@ DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept case 3: return DXGI_FORMAT_R16G16B16A16_SINT; // No 3 channel type case 4: return DXGI_FORMAT_R16G16B16A16_SINT; } - unreachable("Wrong type size"); + unreachable("Unimplemented type size used %x, please report this to a developer.", size); } case CELL_GCM_VERTEX_CMP: { @@ -469,7 +465,7 @@ DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept case 3: return DXGI_FORMAT_R32G32B32_FLOAT; case 4: return DXGI_FORMAT_R32G32B32A32_FLOAT; } - unreachable("Wrong type size"); + unreachable("Unimplemented type size used %x, please report this to a developer.", size); } case CELL_GCM_VERTEX_UB256: { @@ -480,10 +476,10 @@ DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept case 3: return DXGI_FORMAT_R8G8B8A8_UINT; // No 3 channel type case 4: return DXGI_FORMAT_R8G8B8A8_UINT; } - unreachable("Wrong type size"); + unreachable("Unimplemented type size used %x, please report this to a developer.", size); } } - unreachable("Wrong type"); + unreachable("Unimplemented type used %x, please report this to a developer.", size); } D3D12_RECT get_scissor(u32 horizontal, u32 vertical) noexcept From dc5a439ec9e4c5213740fb0636e5d5b4e22db1c6 Mon Sep 17 00:00:00 2001 From: Zangetsu38 Date: Wed, 9 Dec 2015 00:48:14 +0100 Subject: [PATCH 11/13] d3d12: Code style fix for function return --- rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp | 73 +++++++++------------------- 1 file changed, 24 insertions(+), 49 deletions(-) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp index 97300be2c9..710143ee9a 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp @@ -138,55 +138,30 @@ DXGI_FORMAT get_texture_format(int format) noexcept { switch (format) { - case CELL_GCM_TEXTURE_B8: - return DXGI_FORMAT_R8_UNORM; - case CELL_GCM_TEXTURE_A1R5G5B5: - return DXGI_FORMAT_B5G5R5A1_UNORM; - case CELL_GCM_TEXTURE_A4R4G4B4: - return DXGI_FORMAT_B4G4R4A4_UNORM; - case CELL_GCM_TEXTURE_R5G6B5: - return DXGI_FORMAT_B5G6R5_UNORM; - case CELL_GCM_TEXTURE_A8R8G8B8: - return DXGI_FORMAT_R8G8B8A8_UNORM; - case CELL_GCM_TEXTURE_COMPRESSED_DXT1: - return DXGI_FORMAT_BC1_UNORM; - case CELL_GCM_TEXTURE_COMPRESSED_DXT23: - return DXGI_FORMAT_BC2_UNORM; - case CELL_GCM_TEXTURE_COMPRESSED_DXT45: - return DXGI_FORMAT_BC3_UNORM; - case CELL_GCM_TEXTURE_G8B8: - return DXGI_FORMAT_G8R8_G8B8_UNORM; - case CELL_GCM_TEXTURE_R6G5B5: - /*Not native*/ - return DXGI_FORMAT_R8G8B8A8_UNORM; - case CELL_GCM_TEXTURE_DEPTH24_D8: - return DXGI_FORMAT_R32_UINT; - case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: - return DXGI_FORMAT_R32_FLOAT; - case CELL_GCM_TEXTURE_DEPTH16: - return DXGI_FORMAT_R16_UNORM; - case CELL_GCM_TEXTURE_DEPTH16_FLOAT: - return DXGI_FORMAT_R16_FLOAT; - case CELL_GCM_TEXTURE_X16: - return DXGI_FORMAT_R16_UNORM; - case CELL_GCM_TEXTURE_Y16_X16: - return DXGI_FORMAT_R16G16_UNORM; - case CELL_GCM_TEXTURE_R5G5B5A1: - return DXGI_FORMAT_B5G5R5A1_UNORM; - case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: - return DXGI_FORMAT_R16G16B16A16_FLOAT; - case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: - return DXGI_FORMAT_R32G32B32A32_FLOAT; - case CELL_GCM_TEXTURE_X32_FLOAT: - return DXGI_FORMAT_R32_FLOAT; - case CELL_GCM_TEXTURE_D1R5G5B5: - return DXGI_FORMAT_B5G5R5A1_UNORM; - case CELL_GCM_TEXTURE_D8R8G8B8: - return DXGI_FORMAT_R8G8B8A8_UNORM; - case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: - return DXGI_FORMAT_G8R8_G8B8_UNORM; - case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: - return DXGI_FORMAT_R8G8_B8G8_UNORM; + case CELL_GCM_TEXTURE_B8: return DXGI_FORMAT_R8_UNORM; + case CELL_GCM_TEXTURE_A1R5G5B5: return DXGI_FORMAT_B5G5R5A1_UNORM; + case CELL_GCM_TEXTURE_A4R4G4B4: return DXGI_FORMAT_B4G4R4A4_UNORM; + case CELL_GCM_TEXTURE_R5G6B5: return DXGI_FORMAT_B5G6R5_UNORM; + case CELL_GCM_TEXTURE_A8R8G8B8: return DXGI_FORMAT_R8G8B8A8_UNORM; + case CELL_GCM_TEXTURE_COMPRESSED_DXT1: return DXGI_FORMAT_BC1_UNORM; + case CELL_GCM_TEXTURE_COMPRESSED_DXT23: return DXGI_FORMAT_BC2_UNORM; + case CELL_GCM_TEXTURE_COMPRESSED_DXT45: return DXGI_FORMAT_BC3_UNORM; + case CELL_GCM_TEXTURE_G8B8: return DXGI_FORMAT_G8R8_G8B8_UNORM; + case CELL_GCM_TEXTURE_R6G5B5: /*Not native*/ return DXGI_FORMAT_R8G8B8A8_UNORM; + case CELL_GCM_TEXTURE_DEPTH24_D8: return DXGI_FORMAT_R32_UINT; + case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: return DXGI_FORMAT_R32_FLOAT; + case CELL_GCM_TEXTURE_DEPTH16: return DXGI_FORMAT_R16_UNORM; + case CELL_GCM_TEXTURE_DEPTH16_FLOAT: return DXGI_FORMAT_R16_FLOAT; + case CELL_GCM_TEXTURE_X16: return DXGI_FORMAT_R16_UNORM; + case CELL_GCM_TEXTURE_Y16_X16: return DXGI_FORMAT_R16G16_UNORM; + case CELL_GCM_TEXTURE_R5G5B5A1: return DXGI_FORMAT_R8G8B8A8_UNORM; + case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: return DXGI_FORMAT_R16G16B16A16_FLOAT; + case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: return DXGI_FORMAT_R32G32B32A32_FLOAT; + case CELL_GCM_TEXTURE_X32_FLOAT: return DXGI_FORMAT_R32_FLOAT; + case CELL_GCM_TEXTURE_D1R5G5B5: return DXGI_FORMAT_B5G5R5A1_UNORM; + case CELL_GCM_TEXTURE_D8R8G8B8: return DXGI_FORMAT_R8G8B8A8_UNORM; + case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: return DXGI_FORMAT_G8R8_G8B8_UNORM; + case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return DXGI_FORMAT_R8G8_B8G8_UNORM; case CELL_GCM_TEXTURE_Y16_X16_FLOAT: case CELL_GCM_TEXTURE_COMPRESSED_HILO8: case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: From a44c54b42883052221e207c2d90ffc1a6ee8741c Mon Sep 17 00:00:00 2001 From: Zangetsu38 Date: Sun, 13 Dec 2015 23:08:49 +0100 Subject: [PATCH 12/13] d3d12: Fix error Last commit --- rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp index 710143ee9a..6a80435df7 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp @@ -271,11 +271,10 @@ D3D12_PRIMITIVE_TOPOLOGY get_primitive_topology(u8 draw_mode) noexcept case CELL_GCM_PRIMITIVE_LINE_STRIP: return D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; case CELL_GCM_PRIMITIVE_TRIANGLES: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; case CELL_GCM_PRIMITIVE_TRIANGLE_STRIP: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; + case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + case CELL_GCM_PRIMITIVE_QUADS: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; case CELL_GCM_PRIMITIVE_QUAD_STRIP: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; case CELL_GCM_PRIMITIVE_POLYGON: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: - case CELL_GCM_PRIMITIVE_QUADS: - unreachable("Unsupported draw mode used %x, please report this to a developer.", draw_mode); } unreachable("Unimplemented draw mode used %x, please report this to a developer.", draw_mode); } @@ -285,15 +284,15 @@ D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(u8 draw_mode) noexcept switch (draw_mode) { case CELL_GCM_PRIMITIVE_POINTS: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT; + case CELL_GCM_PRIMITIVE_LINES: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE; case CELL_GCM_PRIMITIVE_LINE_STRIP: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE; case CELL_GCM_PRIMITIVE_TRIANGLES: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + case CELL_GCM_PRIMITIVE_TRIANGLE_STRIP: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; case CELL_GCM_PRIMITIVE_QUADS: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; case CELL_GCM_PRIMITIVE_QUAD_STRIP: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - case CELL_GCM_PRIMITIVE_LINES: + case CELL_GCM_PRIMITIVE_POLYGON: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; case CELL_GCM_PRIMITIVE_LINE_LOOP: - case CELL_GCM_PRIMITIVE_TRIANGLE_STRIP: - case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: - case CELL_GCM_PRIMITIVE_POLYGON: unreachable("Unsupported draw mode used %x, please report this to a developer.", draw_mode); } unreachable("Unimplemented draw mode used %x, please report this to a developer.", draw_mode); From 69b3828086d6338052a5a1eccec94ee489368ac4 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Mon, 14 Dec 2015 23:40:05 +0100 Subject: [PATCH 13/13] rsx/common: Vertex program condition swizzle should apply to cc0, not float4(0.) --- rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp index c2874b5a60..e15c2850b9 100644 --- a/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp @@ -253,7 +253,7 @@ std::string VertexProgramDecompiler::GetCond() swizzle += f[d0.mask_w]; swizzle = swizzle == "xyzw" ? "" : "." + swizzle; - return "any(" + compareFunction(cond_string_table[d0.cond], "cc" + std::to_string(d0.cond_reg_sel_1), getFloatTypeName(4) + "(0., 0., 0., 0.)" + swizzle) + ")"; + return "any(" + compareFunction(cond_string_table[d0.cond], "cc" + std::to_string(d0.cond_reg_sel_1) + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)" + swizzle) + ")"; } void VertexProgramDecompiler::AddCodeCond(const std::string& dst, const std::string& src)