mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 03:32:55 +00:00
common/d3d12/gl: Start implementing cubemap sampling
This commit is contained in:
parent
80dc122742
commit
6221fecf3b
@ -325,7 +325,8 @@ public:
|
|||||||
auto& vmfprog = vm::ps3::_ref<CgBinaryFragmentProgram>(ptr + vmprog.program);
|
auto& vmfprog = vm::ps3::_ref<CgBinaryFragmentProgram>(ptr + vmprog.program);
|
||||||
u32 size;
|
u32 size;
|
||||||
u32 ctrl = (vmfprog.outputFromH0 ? 0 : 0x40) | (vmfprog.depthReplace ? 0xe : 0);
|
u32 ctrl = (vmfprog.outputFromH0 ? 0 : 0x40) | (vmfprog.depthReplace ? 0xe : 0);
|
||||||
GLFragmentDecompilerThread(m_glsl_shader, param_array, ptr + vmprog.ucode, size, ctrl).Task();
|
std::vector<texture_dimension> td;
|
||||||
|
GLFragmentDecompilerThread(m_glsl_shader, param_array, ptr + vmprog.ucode, size, ctrl, td).Task();
|
||||||
vm::close();
|
vm::close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,13 @@
|
|||||||
|
|
||||||
#include "FragmentProgramDecompiler.h"
|
#include "FragmentProgramDecompiler.h"
|
||||||
|
|
||||||
FragmentProgramDecompiler::FragmentProgramDecompiler(u32 addr, u32& size, u32 ctrl) :
|
FragmentProgramDecompiler::FragmentProgramDecompiler(u32 addr, u32& size, u32 ctrl, const std::vector<texture_dimension> &texture_dimensions) :
|
||||||
m_addr(addr),
|
m_addr(addr),
|
||||||
m_size(size),
|
m_size(size),
|
||||||
m_const_index(0),
|
m_const_index(0),
|
||||||
m_location(0),
|
m_location(0),
|
||||||
m_ctrl(ctrl)
|
m_ctrl(ctrl),
|
||||||
|
m_texture_dimensions(texture_dimensions)
|
||||||
{
|
{
|
||||||
m_size = 0;
|
m_size = 0;
|
||||||
}
|
}
|
||||||
@ -128,7 +129,7 @@ std::string FragmentProgramDecompiler::AddConst()
|
|||||||
|
|
||||||
std::string FragmentProgramDecompiler::AddTex()
|
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)
|
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_DDY: SetDst(getFunction(FUNCTION::FUNCTION_DFDY)); return true;
|
||||||
case RSX_FP_OPCODE_NRM: SetDst("normalize($0)"); 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_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_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_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_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;
|
case RSX_FP_OPCODE_TXB: SetDst("texture($t, $0.xy, $1.x)"); return true;
|
||||||
|
@ -22,6 +22,7 @@ class FragmentProgramDecompiler
|
|||||||
std::string main;
|
std::string main;
|
||||||
u32 m_addr;
|
u32 m_addr;
|
||||||
u32& m_size;
|
u32& m_size;
|
||||||
|
const std::vector<texture_dimension> m_texture_dimensions;
|
||||||
u32 m_const_index;
|
u32 m_const_index;
|
||||||
u32 m_offset;
|
u32 m_offset;
|
||||||
u32 m_location;
|
u32 m_location;
|
||||||
@ -107,6 +108,6 @@ protected:
|
|||||||
virtual void insertMainEnd(std::stringstream &OS) = 0;
|
virtual void insertMainEnd(std::stringstream &OS) = 0;
|
||||||
public:
|
public:
|
||||||
ParamArray m_parr;
|
ParamArray m_parr;
|
||||||
FragmentProgramDecompiler(u32 addr, u32& size, u32 ctrl);
|
FragmentProgramDecompiler(u32 addr, u32& size, u32 ctrl, const std::vector<texture_dimension> &texture_dimensions);
|
||||||
std::string Decompile();
|
std::string Decompile();
|
||||||
};
|
};
|
||||||
|
@ -15,6 +15,8 @@ enum class FUNCTION {
|
|||||||
FUNCTION_DFDY,
|
FUNCTION_DFDY,
|
||||||
FUNCTION_TEXTURE_SAMPLE,
|
FUNCTION_TEXTURE_SAMPLE,
|
||||||
FUNCTION_TEXTURE_SAMPLE_PROJ,
|
FUNCTION_TEXTURE_SAMPLE_PROJ,
|
||||||
|
FUNCTION_TEXTURE_CUBE_SAMPLE,
|
||||||
|
FUNCTION_TEXTURE_CUBE_SAMPLE_PROJ,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class COMPARE {
|
enum class COMPARE {
|
||||||
|
@ -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 <typename T, size_t block_size_in_bytes, size_t block_edge_in_texel = 1>
|
template <typename T, size_t block_size_in_bytes, size_t block_edge_in_texel = 1>
|
||||||
std::vector<MipmapLevelInfo> copy_texture_data(void *dst, const void *src, size_t widthInBlock, size_t heightInBlock, size_t depth, size_t mipmapCount) noexcept
|
std::vector<MipmapLevelInfo> 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<MipmapLevelInfo> copy_texture_data(void *dst, const void *src, size_
|
|||||||
miplevel_height_in_block = MAX2(miplevel_height_in_block / 2, 1);
|
miplevel_height_in_block = MAX2(miplevel_height_in_block / 2, 1);
|
||||||
miplevel_width_in_block = MAX2(miplevel_width_in_block / 2, 1);
|
miplevel_width_in_block = MAX2(miplevel_width_in_block / 2, 1);
|
||||||
}
|
}
|
||||||
|
offsetInSrc = align(offsetInSrc, 128);
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
@ -249,6 +257,7 @@ std::vector<MipmapLevelInfo> upload_placed_texture(const rsx::texture &texture,
|
|||||||
{
|
{
|
||||||
size_t w = texture.width(), h = texture.height();
|
size_t w = texture.width(), h = texture.height();
|
||||||
size_t depth = texture.depth();
|
size_t depth = texture.depth();
|
||||||
|
if (texture.cubemap()) depth *= 6;
|
||||||
|
|
||||||
int format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
int format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
||||||
|
|
||||||
|
@ -46,6 +46,10 @@ std::string getFunctionImp(FUNCTION f)
|
|||||||
return "$t.Sample($tsampler, $0.xy * $t_scale)";
|
return "$t.Sample($tsampler, $0.xy * $t_scale)";
|
||||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE_PROJ:
|
case FUNCTION::FUNCTION_TEXTURE_SAMPLE_PROJ:
|
||||||
return "$t.Sample($tsampler, ($0.xy / $0.z) * $t_scale)";
|
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:
|
case FUNCTION::FUNCTION_DFDX:
|
||||||
return "ddx($0)";
|
return "ddx($0)";
|
||||||
case FUNCTION::FUNCTION_DFDY:
|
case FUNCTION::FUNCTION_DFDY:
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
#include "Emu/Memory/Memory.h"
|
#include "Emu/Memory/Memory.h"
|
||||||
#include "Emu/System.h"
|
#include "Emu/System.h"
|
||||||
|
|
||||||
D3D12FragmentDecompiler::D3D12FragmentDecompiler(u32 addr, u32& size, u32 ctrl) :
|
D3D12FragmentDecompiler::D3D12FragmentDecompiler(u32 addr, u32& size, u32 ctrl, const std::vector<texture_dimension> &texture_dimensions) :
|
||||||
FragmentProgramDecompiler(addr, size, ctrl)
|
FragmentProgramDecompiler(addr, size, ctrl, texture_dimensions)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -110,7 +110,7 @@ void D3D12FragmentDecompiler::insertConstants(std::stringstream & OS)
|
|||||||
OS << "{" << std::endl;
|
OS << "{" << std::endl;
|
||||||
for (ParamType PT : m_parr.params[PF_PARAM_UNIFORM])
|
for (ParamType PT : m_parr.params[PF_PARAM_UNIFORM])
|
||||||
{
|
{
|
||||||
if (PT.type == "sampler2D")
|
if (PT.type == "sampler2D" || PT.type == "samplerCube")
|
||||||
continue;
|
continue;
|
||||||
for (ParamItem PI : PT.items)
|
for (ParamItem PI : PT.items)
|
||||||
OS << " " << PT.type << " " << PI.name << ";" << std::endl;
|
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])
|
for (ParamType PT : m_parr.params[PF_PARAM_UNIFORM])
|
||||||
{
|
{
|
||||||
if (PT.type != "sampler2D")
|
if (PT.type == "sampler2D")
|
||||||
continue;
|
|
||||||
for (ParamItem PI : PT.items)
|
|
||||||
{
|
{
|
||||||
size_t textureIndex = atoi(PI.name.data() + 3);
|
for (ParamItem PI : PT.items)
|
||||||
OS << "Texture2D " << PI.name << " : register(t" << textureIndex << ");" << std::endl;
|
{
|
||||||
OS << "sampler " << PI.name << "sampler : register(s" << textureIndex << ");" << std::endl;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,5 +20,5 @@ protected:
|
|||||||
virtual void insertMainStart(std::stringstream &OS) override;
|
virtual void insertMainStart(std::stringstream &OS) override;
|
||||||
virtual void insertMainEnd(std::stringstream &OS) override;
|
virtual void insertMainEnd(std::stringstream &OS) override;
|
||||||
public:
|
public:
|
||||||
D3D12FragmentDecompiler(u32 addr, u32& size, u32 ctrl);
|
D3D12FragmentDecompiler(u32 addr, u32& size, u32 ctrl, const std::vector<texture_dimension> &texture_dimensions);
|
||||||
};
|
};
|
||||||
|
@ -56,6 +56,17 @@ bool D3D12GSRender::load_program()
|
|||||||
fragment_program.offset = shader_program & ~0x3;
|
fragment_program.offset = shader_program & ~0x3;
|
||||||
fragment_program.addr = rsx::get_address(fragment_program.offset, (shader_program & 0x3) - 1);
|
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.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 = {};
|
D3D12PipelineProperties prop = {};
|
||||||
prop.Topology = get_primitive_topology_type(draw_mode);
|
prop.Topology = get_primitive_topology_type(draw_mode);
|
||||||
|
@ -147,7 +147,7 @@ struct D3D12Traits
|
|||||||
static
|
static
|
||||||
void RecompileFragmentProgram(RSXFragmentProgram *RSXFP, FragmentProgramData& fragmentProgramData, size_t ID)
|
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();
|
const std::string &shader = FS.Decompile();
|
||||||
fragmentProgramData.Compile(shader, Shader::SHADER_TYPE::SHADER_TYPE_FRAGMENT);
|
fragmentProgramData.Compile(shader, Shader::SHADER_TYPE::SHADER_TYPE_FRAGMENT);
|
||||||
fragmentProgramData.m_textureCount = 0;
|
fragmentProgramData.m_textureCount = 0;
|
||||||
@ -155,7 +155,7 @@ struct D3D12Traits
|
|||||||
{
|
{
|
||||||
for (const ParamItem PI : PT.items)
|
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);
|
size_t texture_unit = atoi(PI.name.c_str() + 3);
|
||||||
fragmentProgramData.m_textureCount = std::max(texture_unit + 1, fragmentProgramData.m_textureCount);
|
fragmentProgramData.m_textureCount = std::max(texture_unit + 1, fragmentProgramData.m_textureCount);
|
||||||
|
@ -52,6 +52,8 @@ ComPtr<ID3D12Resource> upload_single_texture(
|
|||||||
data_heap<ID3D12Resource, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT> &texture_buffer_heap)
|
data_heap<ID3D12Resource, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT> &texture_buffer_heap)
|
||||||
{
|
{
|
||||||
size_t w = texture.width(), h = texture.height();
|
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);
|
int format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
||||||
DXGI_FORMAT dxgi_format = get_texture_format(format);
|
DXGI_FORMAT dxgi_format = get_texture_format(format);
|
||||||
@ -70,7 +72,7 @@ ComPtr<ID3D12Resource> upload_single_texture(
|
|||||||
ThrowIfFailed(device->CreateCommittedResource(
|
ThrowIfFailed(device->CreateCommittedResource(
|
||||||
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
|
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
|
||||||
D3D12_HEAP_FLAG_NONE,
|
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,
|
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||||
nullptr,
|
nullptr,
|
||||||
IID_PPV_ARGS(result.GetAddressOf())
|
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 = {};
|
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.Format = get_texture_format(format);
|
||||||
shared_resource_view_desc.Texture2D.MipLevels = textures[i].mipmap();
|
|
||||||
|
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
|
@ -44,6 +44,10 @@ std::string getFunctionImpl(FUNCTION f)
|
|||||||
return "texture($t, $0.xy)";
|
return "texture($t, $0.xy)";
|
||||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE_PROJ:
|
case FUNCTION::FUNCTION_TEXTURE_SAMPLE_PROJ:
|
||||||
return "textureProj($t, $0.xyz, $1.x)"; // Note: $1.x is bias
|
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:
|
case FUNCTION::FUNCTION_DFDX:
|
||||||
return "dFdx($0)";
|
return "dFdx($0)";
|
||||||
case FUNCTION::FUNCTION_DFDY:
|
case FUNCTION::FUNCTION_DFDY:
|
||||||
|
@ -156,9 +156,9 @@ GLFragmentProgram::~GLFragmentProgram()
|
|||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
void GLFragmentProgram::Decompile(RSXFragmentProgram& prog)
|
void GLFragmentProgram::Decompile(RSXFragmentProgram& prog, const std::vector<texture_dimension> &td)
|
||||||
{
|
{
|
||||||
GLFragmentDecompilerThread decompiler(shader, parr, prog.addr, prog.size, prog.ctrl);
|
GLFragmentDecompilerThread decompiler(shader, parr, prog.addr, prog.size, prog.ctrl, td);
|
||||||
decompiler.Task();
|
decompiler.Task();
|
||||||
for (const ParamType& PT : decompiler.m_parr.params[PF_PARAM_UNIFORM])
|
for (const ParamType& PT : decompiler.m_parr.params[PF_PARAM_UNIFORM])
|
||||||
{
|
{
|
||||||
|
@ -9,8 +9,8 @@ struct GLFragmentDecompilerThread : public FragmentProgramDecompiler
|
|||||||
std::string& m_shader;
|
std::string& m_shader;
|
||||||
ParamArray& m_parrDummy;
|
ParamArray& m_parrDummy;
|
||||||
public:
|
public:
|
||||||
GLFragmentDecompilerThread(std::string& shader, ParamArray& parr, u32 addr, u32& size, u32 ctrl)
|
GLFragmentDecompilerThread(std::string& shader, ParamArray& parr, u32 addr, u32& size, u32 ctrl, const std::vector<texture_dimension> &texture_dimensions)
|
||||||
: FragmentProgramDecompiler(addr, size, ctrl)
|
: FragmentProgramDecompiler(addr, size, ctrl, texture_dimensions)
|
||||||
, m_shader(shader)
|
, m_shader(shader)
|
||||||
, m_parrDummy(parr)
|
, m_parrDummy(parr)
|
||||||
{
|
{
|
||||||
@ -49,8 +49,9 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Decompile a fragment shader located in the PS3's Memory. This function operates synchronously.
|
* 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 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<texture_dimension> &td);
|
||||||
|
|
||||||
/** Compile the decompiled fragment shader into a format we can use with OpenGL. */
|
/** Compile the decompiled fragment shader into a format we can use with OpenGL. */
|
||||||
void Compile();
|
void Compile();
|
||||||
|
@ -1231,6 +1231,16 @@ bool GLGSRender::load_program()
|
|||||||
fragment_program.addr = rsx::get_address(fragment_program.offset, (shader_program & 0x3) - 1);
|
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.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 = m_prog_buffer.getGraphicPipelineState(&vertex_program, &fragment_program, nullptr, nullptr);
|
||||||
__glcheck m_program->use();
|
__glcheck m_program->use();
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ struct GLTraits
|
|||||||
static
|
static
|
||||||
void RecompileFragmentProgram(RSXFragmentProgram *RSXFP, FragmentProgramData& fragmentProgramData, size_t ID)
|
void RecompileFragmentProgram(RSXFragmentProgram *RSXFP, FragmentProgramData& fragmentProgramData, size_t ID)
|
||||||
{
|
{
|
||||||
fragmentProgramData.Decompile(*RSXFP);
|
fragmentProgramData.Decompile(*RSXFP, RSXFP->texture_dimensions);
|
||||||
fragmentProgramData.Compile();
|
fragmentProgramData.Compile();
|
||||||
//checkForGlError("m_fragment_prog.Compile");
|
//checkForGlError("m_fragment_prog.Compile");
|
||||||
|
|
||||||
|
@ -204,12 +204,20 @@ static const std::string rsx_fp_op_names[] =
|
|||||||
"NULL", "BRK", "CAL", "IFE", "LOOP", "REP", "RET"
|
"NULL", "BRK", "CAL", "IFE", "LOOP", "REP", "RET"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class texture_dimension
|
||||||
|
{
|
||||||
|
texture_dimension_2d,
|
||||||
|
texture_dimension_2d_array,
|
||||||
|
texture_dimension_cubemap,
|
||||||
|
};
|
||||||
|
|
||||||
struct RSXFragmentProgram
|
struct RSXFragmentProgram
|
||||||
{
|
{
|
||||||
u32 size;
|
u32 size;
|
||||||
u32 addr;
|
u32 addr;
|
||||||
u32 offset;
|
u32 offset;
|
||||||
u32 ctrl;
|
u32 ctrl;
|
||||||
|
std::vector<texture_dimension> texture_dimensions;
|
||||||
|
|
||||||
RSXFragmentProgram()
|
RSXFragmentProgram()
|
||||||
: size(0)
|
: size(0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user