rsx/common/d3d12: Support for texture 1d too.

They are used in after burner climax
This commit is contained in:
Vincent Lejeune 2016-01-27 00:34:34 +01:00
parent e1eb075604
commit 5f35f2ac7d
13 changed files with 151 additions and 89 deletions

View File

@ -130,6 +130,9 @@ std::string FragmentProgramDecompiler::AddTex()
std::string sampler;
switch (m_prog.get_texture_dimension(dst.tex_num))
{
case texture_dimension::texture_dimension_1d:
sampler = "sampler1D";
break;
case texture_dimension::texture_dimension_cubemap:
sampler = "samplerCube";
break;
@ -439,11 +442,14 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode)
case RSX_FP_OPCODE_TEX:
switch (m_prog.get_texture_dimension(dst.tex_num))
{
case texture_dimension::texture_dimension_1d:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE1D));
return true;
case texture_dimension::texture_dimension_2d:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE));
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D));
return true;
case texture_dimension::texture_dimension_cubemap:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE));
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE));
return true;
case texture_dimension::texture_dimension_3d:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE3D));
@ -454,11 +460,14 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode)
case RSX_FP_OPCODE_TXP:
switch (m_prog.get_texture_dimension(dst.tex_num))
{
case texture_dimension::texture_dimension_1d:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_PROJ));
return true;
case texture_dimension::texture_dimension_2d:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE_PROJ));
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_PROJ));
return true;
case texture_dimension::texture_dimension_cubemap:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE_PROJ));
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_PROJ));
return true;
case texture_dimension::texture_dimension_3d:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_PROJ));
@ -471,11 +480,14 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode)
case RSX_FP_OPCODE_TXL:
switch (m_prog.get_texture_dimension(dst.tex_num))
{
case texture_dimension::texture_dimension_1d:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_LOD));
return true;
case texture_dimension::texture_dimension_2d:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE_LOD));
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_LOD));
return true;
case texture_dimension::texture_dimension_cubemap:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE_LOD));
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_LOD));
return true;
case texture_dimension::texture_dimension_3d:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_LOD));

View File

@ -13,12 +13,15 @@ enum class FUNCTION {
FUNCTION_FRACT,
FUNCTION_DFDX,
FUNCTION_DFDY,
FUNCTION_TEXTURE_SAMPLE,
FUNCTION_TEXTURE_SAMPLE_PROJ,
FUNCTION_TEXTURE_SAMPLE_LOD,
FUNCTION_TEXTURE_CUBE_SAMPLE,
FUNCTION_TEXTURE_CUBE_SAMPLE_PROJ,
FUNCTION_TEXTURE_CUBE_SAMPLE_LOD,
FUNCTION_TEXTURE_SAMPLE1D,
FUNCTION_TEXTURE_SAMPLE1D_PROJ,
FUNCTION_TEXTURE_SAMPLE1D_LOD,
FUNCTION_TEXTURE_SAMPLE2D,
FUNCTION_TEXTURE_SAMPLE2D_PROJ,
FUNCTION_TEXTURE_SAMPLE2D_LOD,
FUNCTION_TEXTURE_SAMPLECUBE,
FUNCTION_TEXTURE_SAMPLECUBE_PROJ,
FUNCTION_TEXTURE_SAMPLECUBE_LOD,
FUNCTION_TEXTURE_SAMPLE3D,
FUNCTION_TEXTURE_SAMPLE3D_PROJ,
FUNCTION_TEXTURE_SAMPLE3D_LOD,

View File

@ -270,7 +270,13 @@ std::vector<MipmapLevelInfo> upload_placed_texture(const rsx::texture &texture,
u16 depth;
u8 layer;
if (texture.dimension() == 2)
if (texture.dimension() == 1)
{
depth = 1;
layer = 1;
h = 1;
}
else if (texture.dimension() == 2)
{
depth = 1;
layer = texture.cubemap() ? 6 : 1;

View File

@ -42,17 +42,23 @@ std::string getFunctionImp(FUNCTION f)
return "float4(1., 1., 1., 1.)";
case FUNCTION::FUNCTION_FRACT:
return "frac($0)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE:
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D:
return "$t.Sample($tsampler, $0.x)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_PROJ:
return "$t.Sample($tsampler, ($0.x / $0.w))";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_LOD:
return "$t.SampleLevel($tsampler, $0.x, $1)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D:
return "$t.Sample($tsampler, $0.xy * $t_scale)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE_PROJ:
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_PROJ:
return "$t.Sample($tsampler, ($0.xy / $0.w) * $t_scale)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE_LOD:
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_LOD:
return "$t.SampleLevel($tsampler, $0.xy * $t_scale, $1)";
case FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE:
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE:
return "$t.Sample($tsampler, $0.xyz)";
case FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE_PROJ:
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_PROJ:
return "$t.Sample($tsampler, ($0.xyz / $0.w))";
case FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE_LOD:
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_LOD:
return "$t.SampleLevel($tsampler, $0.xyz, $1)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D:
return "$t.Sample($tsampler, $0.xyz)";

View File

@ -109,18 +109,27 @@ void D3D12FragmentDecompiler::insertConstants(std::stringstream & OS)
OS << "{" << std::endl;
for (const ParamType &PT : m_parr.params[PF_PARAM_UNIFORM])
{
if (PT.type == "sampler2D" || PT.type == "samplerCube" || PT.type == "sampler3D")
if (PT.type == "sampler1D" || PT.type == "sampler2D" || PT.type == "samplerCube" || PT.type == "sampler3D")
continue;
for (ParamItem PI : PT.items)
for (const ParamItem &PI : PT.items)
OS << " " << PT.type << " " << PI.name << ";" << std::endl;
}
OS << "};" << std::endl << std::endl;
for (const ParamType &PT : m_parr.params[PF_PARAM_UNIFORM])
{
if (PT.type == "sampler2D")
if (PT.type == "sampler1D")
{
for (ParamItem PI : PT.items)
for (const ParamItem &PI : PT.items)
{
size_t textureIndex = atoi(PI.name.data() + 3);
OS << "Texture1D " << PI.name << " : register(t" << textureIndex + 16 << ");" << std::endl;
OS << "sampler " << PI.name << "sampler : register(s" << textureIndex << ");" << std::endl;
}
}
else if (PT.type == "sampler2D")
{
for (const ParamItem &PI : PT.items)
{
size_t textureIndex = atoi(PI.name.data() + 3);
OS << "Texture2D " << PI.name << " : register(t" << textureIndex + 16 << ");" << std::endl;

View File

@ -39,25 +39,7 @@ void Shader::Compile(const std::string &code, SHADER_TYPE st)
void D3D12GSRender::load_program()
{
m_vertex_program = get_current_vertex_program();
u32 shader_program = rsx::method_registers[NV4097_SET_SHADER_PROGRAM];
m_fragment_program.offset = shader_program & ~0x3;
m_fragment_program.addr = vm::base(rsx::get_address(m_fragment_program.offset, (shader_program & 0x3) - 1));
m_fragment_program.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL];
std::array<texture_dimension, 16> texture_dimensions;
for (u32 i = 0; i < rsx::limits::textures_count; ++i)
{
if (!textures[i].enabled())
texture_dimensions[i] = texture_dimension::texture_dimension_2d;
else if (textures[i].cubemap())
texture_dimensions[i] = texture_dimension::texture_dimension_cubemap;
else if (textures[i].dimension() == 3)
texture_dimensions[i] = texture_dimension::texture_dimension_3d;
else
texture_dimensions[i] = texture_dimension::texture_dimension_2d;
}
m_fragment_program.set_texture_dimension(texture_dimensions);
m_fragment_program = get_current_fragment_program();
D3D12PipelineProperties prop = {};
prop.Topology = get_primitive_topology_type(draw_mode);

View File

@ -119,7 +119,7 @@ struct D3D12Traits
{
for (const ParamItem PI : PT.items)
{
if (PT.type == "sampler2D" || PT.type == "samplerCube" || PT.type == "sampler3D")
if (PT.type == "sampler1D" || PT.type == "sampler2D" || PT.type == "samplerCube" || PT.type == "sampler3D")
{
size_t texture_unit = atoi(PI.name.c_str() + 3);
fragmentProgramData.m_textureCount = std::max(texture_unit + 1, fragmentProgramData.m_textureCount);

View File

@ -47,7 +47,11 @@ namespace
const u8 format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
DXGI_FORMAT dxgi_format = get_texture_format(format);
if (texture.dimension() == 2) // 2D texture or cubemap
if (texture.dimension() == 1) // 1D texture or cubemap
{
return CD3DX12_RESOURCE_DESC::Tex1D(dxgi_format, texture.width(), 1, texture.mipmap());
}
else if (texture.dimension() == 2) // 2D texture or cubemap
{
// if (texture.depth() < 2);
size_t depth = (texture.cubemap()) ? 6 : 1;
@ -135,6 +139,36 @@ void update_existing_texture(
command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(existing_texture, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_GENERIC_READ));
}
D3D12_SHADER_RESOURCE_VIEW_DESC get_srv_descriptor_with_dimensions(const rsx::texture &tex)
{
D3D12_SHADER_RESOURCE_VIEW_DESC shared_resource_view_desc = {};
if (tex.dimension() == 1)
{
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D;
shared_resource_view_desc.Texture1D.MipLevels = tex.mipmap();
return shared_resource_view_desc;
}
if (tex.dimension() == 2)
{
if (tex.cubemap())
{
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
shared_resource_view_desc.TextureCube.MipLevels = tex.mipmap();
return shared_resource_view_desc;
}
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
shared_resource_view_desc.Texture2D.MipLevels = tex.mipmap();
return shared_resource_view_desc;
}
if (tex.dimension() == 3)
{
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D;
shared_resource_view_desc.Texture3D.MipLevels = tex.mipmap();
return shared_resource_view_desc;
}
throw EXCEPTION("Wrong texture dimension %d", tex.dimension());
}
}
void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_list, size_t descriptor_index, size_t texture_count)
@ -213,22 +247,7 @@ void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_
m_texture_cache.store_and_protect_data(texaddr, texaddr, get_texture_size(textures[i]), format, w, h, textures[i].depth(), textures[i].mipmap(), tex);
}
D3D12_SHADER_RESOURCE_VIEW_DESC shared_resource_view_desc = {};
if (textures[i].cubemap())
{
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
shared_resource_view_desc.TextureCube.MipLevels = textures[i].mipmap();
}
else if (textures[i].dimension() == 2)
{
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
shared_resource_view_desc.Texture2D.MipLevels = textures[i].mipmap();
}
else if (textures[i].dimension() == 3)
{
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D;
shared_resource_view_desc.Texture2D.MipLevels = textures[i].mipmap();
}
D3D12_SHADER_RESOURCE_VIEW_DESC shared_resource_view_desc = get_srv_descriptor_with_dimensions(textures[i]);
shared_resource_view_desc.Format = get_texture_format(format);
switch (format)

View File

@ -40,17 +40,23 @@ std::string getFunctionImpl(FUNCTION f)
return "vec4(1., 1., 1., 1.)";
case FUNCTION::FUNCTION_FRACT:
return "fract($0)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE:
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D:
return "texture($t, $0.x)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_PROJ:
return "textureProj($t, $0.x, $1.x)"; // Note: $1.x is bias
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_LOD:
return "textureLod($t, $0.x, $1)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D:
return "texture($t, $0.xy)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE_PROJ:
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_PROJ:
return "textureProj($t, $0.xyz, $1.x)"; // Note: $1.x is bias
case FUNCTION::FUNCTION_TEXTURE_SAMPLE_LOD:
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_LOD:
return "textureLod($t, $0.xy, $1)";
case FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE:
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE:
return "texture($t, $0.xyz)";
case FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE_PROJ:
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_PROJ:
return "textureProj($t, $0.xyzw, $1.x)"; // Note: $1.x is bias
case FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE_LOD:
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_LOD:
return "textureLod($t, $0.xyz, $1)";
case FUNCTION::FUNCTION_DFDX:
return "dFdx($0)";

View File

@ -738,25 +738,7 @@ bool GLGSRender::load_program()
{
#if 1
RSXVertexProgram vertex_program = get_current_vertex_program();
RSXFragmentProgram fragment_program;
u32 shader_program = rsx::method_registers[NV4097_SET_SHADER_PROGRAM];
fragment_program.offset = shader_program & ~0x3;
fragment_program.addr = vm::base(rsx::get_address(fragment_program.offset, (shader_program & 0x3) - 1));
fragment_program.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL];
std::array<texture_dimension, 16> texture_dimensions;
for (u32 i = 0; i < rsx::limits::textures_count; ++i)
{
if (!textures[i].enabled())
texture_dimensions[i] = texture_dimension::texture_dimension_2d;
else if (textures[i].cubemap())
texture_dimensions[i] = texture_dimension::texture_dimension_cubemap;
else if (textures[i].dimension() == 3)
texture_dimensions[i] = texture_dimension::texture_dimension_3d;
else
texture_dimensions[i] = texture_dimension::texture_dimension_2d;
}
fragment_program.set_texture_dimension(texture_dimensions);
RSXFragmentProgram fragment_program = get_current_fragment_program();
__glcheck m_program = &m_prog_buffer.getGraphicPipelineState(vertex_program, fragment_program, nullptr);
__glcheck m_program->use();

View File

@ -207,9 +207,10 @@ static const std::string rsx_fp_op_names[] =
enum class texture_dimension : u8
{
texture_dimension_2d = 0,
texture_dimension_cubemap = 1,
texture_dimension_3d = 2,
texture_dimension_1d = 0,
texture_dimension_2d = 1,
texture_dimension_cubemap = 2,
texture_dimension_3d = 3,
};
struct RSXFragmentProgram

View File

@ -656,6 +656,42 @@ namespace rsx
return result;
}
RSXFragmentProgram thread::get_current_fragment_program() const
{
RSXFragmentProgram result = {};
u32 shader_program = rsx::method_registers[NV4097_SET_SHADER_PROGRAM];
result.offset = shader_program & ~0x3;
result.addr = vm::base(rsx::get_address(result.offset, (shader_program & 0x3) - 1));
result.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL];
result.unnormalized_coords = 0;
std::array<texture_dimension, 16> texture_dimensions;
for (u32 i = 0; i < rsx::limits::textures_count; ++i)
{
if (!textures[i].enabled())
texture_dimensions[i] = texture_dimension::texture_dimension_2d;
else if (textures[i].dimension() == 1)
texture_dimensions[i] = texture_dimension::texture_dimension_1d;
else if (textures[i].dimension() == 2)
{
if (textures[i].cubemap())
texture_dimensions[i] = texture_dimension::texture_dimension_cubemap;
else
texture_dimensions[i] = texture_dimension::texture_dimension_2d;
}
else if (textures[i].dimension() == 3)
texture_dimensions[i] = texture_dimension::texture_dimension_3d;
else
throw EXCEPTION("Unable to determine texture dimension");
if (textures[i].enabled() && (textures[i].format() & CELL_GCM_TEXTURE_UN))
result.unnormalized_coords |= (1 << i);
}
result.set_texture_dimension(texture_dimensions);
return result;
}
void thread::reset()
{
//setup method registers

View File

@ -293,7 +293,7 @@ namespace rsx
std::array<u32, 4> get_color_surface_addresses() const;
u32 get_zeta_surface_address() const;
RSXVertexProgram get_current_vertex_program() const;
RSXFragmentProgram get_current_fragment_program() const;
public:
u32 draw_array_count;
u32 draw_array_first;