mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-01-08 08:00:44 +01:00
fix: shadows
This commit is contained in:
parent
5c246d55bd
commit
a38ddb5fc2
@ -2187,6 +2187,7 @@ static void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContex
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto texDim = shaderContext->shader->textureUnitDim[texInstruction->textureFetch.textureIndex];
|
auto texDim = shaderContext->shader->textureUnitDim[texInstruction->textureFetch.textureIndex];
|
||||||
|
bool isCompare = shaderContext->shader->textureUsesDepthCompare[texInstruction->textureFetch.textureIndex];
|
||||||
|
|
||||||
char tempBuffer0[32];
|
char tempBuffer0[32];
|
||||||
char tempBuffer1[32];
|
char tempBuffer1[32];
|
||||||
@ -2212,6 +2213,7 @@ static void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContex
|
|||||||
}
|
}
|
||||||
// texture sampler opcode
|
// texture sampler opcode
|
||||||
uint32 texOpcode = texInstruction->opcode;
|
uint32 texOpcode = texInstruction->opcode;
|
||||||
|
// TODO: is this needed?
|
||||||
if (shaderContext->shaderType == LatteConst::ShaderType::Vertex)
|
if (shaderContext->shaderType == LatteConst::ShaderType::Vertex)
|
||||||
{
|
{
|
||||||
// vertex shader forces LOD to zero, but certain sampler types don't support textureLod(...) API
|
// vertex shader forces LOD to zero, but certain sampler types don't support textureLod(...) API
|
||||||
@ -2275,7 +2277,10 @@ static void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContex
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
src->addFmt("sample(samplr{}, ", texInstruction->textureFetch.textureIndex);
|
src->add("sample");
|
||||||
|
if (isCompare)
|
||||||
|
src->add("_compare");
|
||||||
|
src->addFmt("(samplr{}, ", texInstruction->textureFetch.textureIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for textureGather() add shift (todo: depends on rounding mode set in sampler registers?)
|
// for textureGather() add shift (todo: depends on rounding mode set in sampler registers?)
|
||||||
@ -2493,61 +2498,68 @@ static void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContex
|
|||||||
src->addFmt(",int3({},{},{})", texInstruction->textureFetch.offsetX/2, texInstruction->textureFetch.offsetY/2, texInstruction->textureFetch.offsetZ/2);
|
src->addFmt(",int3({},{},{})", texInstruction->textureFetch.offsetX/2, texInstruction->textureFetch.offsetY/2, texInstruction->textureFetch.offsetZ/2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// lod bias
|
|
||||||
if( texOpcode == GPU7_TEX_INST_SAMPLE_C || texOpcode == GPU7_TEX_INST_SAMPLE_C_LZ )
|
|
||||||
{
|
|
||||||
src->add(").");
|
|
||||||
|
|
||||||
if (numWrittenElements > 1)
|
// lod bias (TODO: wht?)
|
||||||
{
|
|
||||||
// result is copied into multiple channels
|
src->add(")");
|
||||||
for (sint32 f = 0; f < numWrittenElements; f++)
|
// sample_compare doesn't return a float
|
||||||
{
|
if (!isCompare)
|
||||||
cemu_assert_debug(texInstruction->dstSel[f] == 0); // only x component is defined
|
{
|
||||||
src->add("x");
|
if( texOpcode == GPU7_TEX_INST_SAMPLE_C || texOpcode == GPU7_TEX_INST_SAMPLE_C_LZ )
|
||||||
}
|
{
|
||||||
}
|
src->add(".");
|
||||||
else
|
|
||||||
{
|
if (numWrittenElements > 1)
|
||||||
src->add("x");
|
{
|
||||||
}
|
// result is copied into multiple channels
|
||||||
}
|
for (sint32 f = 0; f < numWrittenElements; f++)
|
||||||
else
|
{
|
||||||
{
|
cemu_assert_debug(texInstruction->dstSel[f] == 0); // only x component is defined
|
||||||
src->add(").");
|
src->add("x");
|
||||||
for (sint32 f = 0; f < 4; f++)
|
}
|
||||||
{
|
}
|
||||||
if( texInstruction->dstSel[f] < 4 )
|
else
|
||||||
{
|
{
|
||||||
uint8 elemIndex = texInstruction->dstSel[f];
|
src->add("x");
|
||||||
if (texOpcode == GPU7_TEX_INST_FETCH4)
|
}
|
||||||
{
|
}
|
||||||
// 's textureGather() and GPU7's FETCH4 instruction have a different order of elements
|
else
|
||||||
// xyzw: top-left, top-right, bottom-right, bottom-left
|
{
|
||||||
// textureGather xyzw
|
src->add(".");
|
||||||
// fetch4 yzxw
|
for (sint32 f = 0; f < 4; f++)
|
||||||
// translate index from fetch4 to textureGather order
|
{
|
||||||
static uint8 fetchToGather[4] =
|
if( texInstruction->dstSel[f] < 4 )
|
||||||
{
|
{
|
||||||
2, // x -> z
|
uint8 elemIndex = texInstruction->dstSel[f];
|
||||||
0, // y -> x
|
if (texOpcode == GPU7_TEX_INST_FETCH4)
|
||||||
1, // z -> y
|
{
|
||||||
3, // w -> w
|
// 's textureGather() and GPU7's FETCH4 instruction have a different order of elements
|
||||||
};
|
// xyzw: top-left, top-right, bottom-right, bottom-left
|
||||||
elemIndex = fetchToGather[elemIndex];
|
// textureGather xyzw
|
||||||
}
|
// fetch4 yzxw
|
||||||
src->add(resultElemTable[elemIndex]);
|
// translate index from fetch4 to textureGather order
|
||||||
numWrittenElements++;
|
static uint8 fetchToGather[4] =
|
||||||
}
|
{
|
||||||
else if( texInstruction->dstSel[f] == 7 )
|
2, // x -> z
|
||||||
{
|
0, // y -> x
|
||||||
// masked and not written
|
1, // z -> y
|
||||||
}
|
3, // w -> w
|
||||||
else
|
};
|
||||||
{
|
elemIndex = fetchToGather[elemIndex];
|
||||||
cemu_assert_unimplemented();
|
}
|
||||||
}
|
src->add(resultElemTable[elemIndex]);
|
||||||
}
|
numWrittenElements++;
|
||||||
|
}
|
||||||
|
else if( texInstruction->dstSel[f] == 7 )
|
||||||
|
{
|
||||||
|
// masked and not written
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cemu_assert_unimplemented();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
src->add(");");
|
src->add(");");
|
||||||
|
|
||||||
|
@ -224,6 +224,7 @@ namespace LatteDecompiler
|
|||||||
src->add("#define GET_FRAGCOORD() vec4(in.position.xy * supportBuffer.fragCoordScale.xy, in.position.z, 1.0 / in.position.w)" _CRLF);
|
src->add("#define GET_FRAGCOORD() vec4(in.position.xy * supportBuffer.fragCoordScale.xy, in.position.z, 1.0 / in.position.w)" _CRLF);
|
||||||
|
|
||||||
src->add("struct FragmentIn {" _CRLF);
|
src->add("struct FragmentIn {" _CRLF);
|
||||||
|
src->add("float4 position [[position]];" _CRLF);
|
||||||
|
|
||||||
LatteShaderPSInputTable* psInputTable = LatteSHRC_GetPSInputTable();
|
LatteShaderPSInputTable* psInputTable = LatteSHRC_GetPSInputTable();
|
||||||
for (sint32 i = 0; i < psInputTable->count; i++)
|
for (sint32 i = 0; i < psInputTable->count; i++)
|
||||||
@ -271,7 +272,7 @@ namespace LatteDecompiler
|
|||||||
// generate depth output for pixel shader
|
// generate depth output for pixel shader
|
||||||
if (decompilerContext->shader->depthWritten)
|
if (decompilerContext->shader->depthWritten)
|
||||||
{
|
{
|
||||||
src->add("float passDepth [[depth]];" _CRLF);
|
src->add("float passDepth [[depth(any)]];" _CRLF);
|
||||||
}
|
}
|
||||||
|
|
||||||
src->add("};" _CRLF _CRLF);
|
src->add("};" _CRLF _CRLF);
|
||||||
@ -323,26 +324,31 @@ namespace LatteDecompiler
|
|||||||
|
|
||||||
src->add(", ");
|
src->add(", ");
|
||||||
|
|
||||||
|
if (shaderContext->shader->textureUsesDepthCompare[i])
|
||||||
|
src->add("depth");
|
||||||
|
else
|
||||||
|
src->add("texture");
|
||||||
|
|
||||||
if (shaderContext->shader->textureIsIntegerFormat[i])
|
if (shaderContext->shader->textureIsIntegerFormat[i])
|
||||||
{
|
{
|
||||||
// integer samplers
|
// integer samplers
|
||||||
if (shaderContext->shader->textureUnitDim[i] == Latte::E_DIM::DIM_1D)
|
if (shaderContext->shader->textureUnitDim[i] == Latte::E_DIM::DIM_1D)
|
||||||
src->add("texture1d<uint>");
|
src->add("1d<uint>");
|
||||||
else if (shaderContext->shader->textureUnitDim[i] == Latte::E_DIM::DIM_2D || shaderContext->shader->textureUnitDim[i] == Latte::E_DIM::DIM_2D_MSAA)
|
else if (shaderContext->shader->textureUnitDim[i] == Latte::E_DIM::DIM_2D || shaderContext->shader->textureUnitDim[i] == Latte::E_DIM::DIM_2D_MSAA)
|
||||||
src->add("texture2d<uint>");
|
src->add("2d<uint>");
|
||||||
else
|
else
|
||||||
cemu_assert_unimplemented();
|
cemu_assert_unimplemented();
|
||||||
}
|
}
|
||||||
else if (shaderContext->shader->textureUnitDim[i] == Latte::E_DIM::DIM_2D || shaderContext->shader->textureUnitDim[i] == Latte::E_DIM::DIM_2D_MSAA)
|
else if (shaderContext->shader->textureUnitDim[i] == Latte::E_DIM::DIM_2D || shaderContext->shader->textureUnitDim[i] == Latte::E_DIM::DIM_2D_MSAA)
|
||||||
src->add("texture2d<float>");
|
src->add("2d<float>");
|
||||||
else if (shaderContext->shader->textureUnitDim[i] == Latte::E_DIM::DIM_1D)
|
else if (shaderContext->shader->textureUnitDim[i] == Latte::E_DIM::DIM_1D)
|
||||||
src->add("texture1d<float>");
|
src->add("1d<float>");
|
||||||
else if (shaderContext->shader->textureUnitDim[i] == Latte::E_DIM::DIM_2D_ARRAY)
|
else if (shaderContext->shader->textureUnitDim[i] == Latte::E_DIM::DIM_2D_ARRAY)
|
||||||
src->add("texture2d_array<float>");
|
src->add("2d_array<float>");
|
||||||
else if (shaderContext->shader->textureUnitDim[i] == Latte::E_DIM::DIM_CUBEMAP)
|
else if (shaderContext->shader->textureUnitDim[i] == Latte::E_DIM::DIM_CUBEMAP)
|
||||||
src->add("texturecube_array<float>");
|
src->add("cube_array<float>");
|
||||||
else if (shaderContext->shader->textureUnitDim[i] == Latte::E_DIM::DIM_3D)
|
else if (shaderContext->shader->textureUnitDim[i] == Latte::E_DIM::DIM_3D)
|
||||||
src->add("texture3d<float>");
|
src->add("3d<float>");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cemu_assert_unimplemented();
|
cemu_assert_unimplemented();
|
||||||
|
@ -39,11 +39,12 @@ MTL::Texture* LatteTextureViewMtl::GetSwizzledView(uint32 gpuSamplerSwizzle)
|
|||||||
sint32 freeIndex = -1;
|
sint32 freeIndex = -1;
|
||||||
for (sint32 i = 0; i < std::size(m_viewCache); i++)
|
for (sint32 i = 0; i < std::size(m_viewCache); i++)
|
||||||
{
|
{
|
||||||
if (m_viewCache[i].key == gpuSamplerSwizzle)
|
const auto& entry = m_viewCache[i];
|
||||||
|
if (entry.key == gpuSamplerSwizzle)
|
||||||
{
|
{
|
||||||
return m_viewCache[i].texture;
|
return entry.texture;
|
||||||
}
|
}
|
||||||
else if (m_viewCache[i].key == INVALID_SWIZZLE && freeIndex == -1)
|
else if (entry.key == INVALID_SWIZZLE && freeIndex == -1)
|
||||||
{
|
{
|
||||||
freeIndex = i;
|
freeIndex = i;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ private:
|
|||||||
struct {
|
struct {
|
||||||
uint32 key;
|
uint32 key;
|
||||||
MTL::Texture* texture;
|
MTL::Texture* texture;
|
||||||
} m_viewCache[4] = {{INVALID_SWIZZLE, nullptr}};
|
} m_viewCache[4] = {{INVALID_SWIZZLE, nullptr}, {INVALID_SWIZZLE, nullptr}, {INVALID_SWIZZLE, nullptr}, {INVALID_SWIZZLE, nullptr}};
|
||||||
std::unordered_map<uint32, MTL::Texture*> m_fallbackViewCache;
|
std::unordered_map<uint32, MTL::Texture*> m_fallbackViewCache;
|
||||||
|
|
||||||
MTL::Texture* CreateSwizzledView(uint32 gpuSamplerSwizzle);
|
MTL::Texture* CreateSwizzledView(uint32 gpuSamplerSwizzle);
|
||||||
|
@ -30,12 +30,10 @@ MTL::DepthStencilState* MetalDepthStencilCache::GetDepthStencilState(const Latte
|
|||||||
MTL::DepthStencilDescriptor* desc = MTL::DepthStencilDescriptor::alloc()->init();
|
MTL::DepthStencilDescriptor* desc = MTL::DepthStencilDescriptor::alloc()->init();
|
||||||
desc->setDepthWriteEnabled(depthWriteEnable);
|
desc->setDepthWriteEnabled(depthWriteEnable);
|
||||||
|
|
||||||
auto depthCompareFunc = GetMtlCompareFunc(depthFunc);
|
if (depthEnable)
|
||||||
if (!depthEnable)
|
|
||||||
{
|
{
|
||||||
depthCompareFunc = MTL::CompareFunctionAlways;
|
desc->setDepthCompareFunction(GetMtlCompareFunc(depthFunc));
|
||||||
}
|
}
|
||||||
desc->setDepthCompareFunction(depthCompareFunc);
|
|
||||||
|
|
||||||
// Stencil state
|
// Stencil state
|
||||||
bool stencilEnable = LatteGPUState.contextNew.DB_DEPTH_CONTROL.get_STENCIL_ENABLE();
|
bool stencilEnable = LatteGPUState.contextNew.DB_DEPTH_CONTROL.get_STENCIL_ENABLE();
|
||||||
|
@ -105,6 +105,7 @@ MetalRestridedBufferRange MetalVertexBufferCache::RestrideBufferIfNeeded(MTL::Bu
|
|||||||
{
|
{
|
||||||
memcpy(newPtr + elem * newStride, oldPtr + elem * stride, stride);
|
memcpy(newPtr + elem * newStride, oldPtr + elem * stride, stride);
|
||||||
}
|
}
|
||||||
|
debug_printf("Restrided vertex buffer (old stride: %zu, new stride: %zu, old size: %zu, new size: %zu)\n", stride, newStride, vertexBufferRange->size, newSize);
|
||||||
|
|
||||||
restrideInfo.memoryInvalidated = false;
|
restrideInfo.memoryInvalidated = false;
|
||||||
restrideInfo.lastStride = newStride;
|
restrideInfo.lastStride = newStride;
|
||||||
|
@ -43,7 +43,6 @@ MTL::RenderPipelineState* MetalPipelineCache::GetPipelineState(const LatteFetchS
|
|||||||
|
|
||||||
auto attribute = vertexDescriptor->attributes()->object(semanticId);
|
auto attribute = vertexDescriptor->attributes()->object(semanticId);
|
||||||
attribute->setOffset(attr.offset);
|
attribute->setOffset(attr.offset);
|
||||||
// Bind from the end to not conflict with uniform buffers
|
|
||||||
attribute->setBufferIndex(GET_MTL_VERTEX_BUFFER_INDEX(attr.attributeBufferIndex));
|
attribute->setBufferIndex(GET_MTL_VERTEX_BUFFER_INDEX(attr.attributeBufferIndex));
|
||||||
attribute->setFormat(GetMtlVertexFormat(attr.format));
|
attribute->setFormat(GetMtlVertexFormat(attr.format));
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "Metal/MTLResource.hpp"
|
#include "Metal/MTLResource.hpp"
|
||||||
#include "Metal/MTLTypes.hpp"
|
#include "Metal/MTLTypes.hpp"
|
||||||
#include "gui/guiWrapper.h"
|
#include "gui/guiWrapper.h"
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
extern bool hasValidFramebufferAttached;
|
extern bool hasValidFramebufferAttached;
|
||||||
|
|
||||||
@ -596,8 +597,7 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
|
|||||||
debug_printf("no vertex function, skipping draw\n");
|
debug_printf("no vertex function, skipping draw\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const auto fetchShader = LatteSHRC_GetActiveFetchShader();
|
||||||
auto fetchShader = vertexShader->compatibleFetchShader;
|
|
||||||
|
|
||||||
// Render pipeline state
|
// Render pipeline state
|
||||||
MTL::RenderPipelineState* renderPipelineState = m_pipelineCache->GetPipelineState(fetchShader, vertexShader, pixelShader, m_state.activeFBO, LatteGPUState.contextNew);
|
MTL::RenderPipelineState* renderPipelineState = m_pipelineCache->GetPipelineState(fetchShader, vertexShader, pixelShader, m_state.activeFBO, LatteGPUState.contextNew);
|
||||||
|
Loading…
Reference in New Issue
Block a user