1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-26 04:32:35 +01:00

rsx/common: Use an help texture_dimension_extended to handle cubemap more cleanly.

This commit is contained in:
Vincent Lejeune 2016-03-30 21:52:29 +02:00
parent b7c539ad7a
commit 91d0229bc5
8 changed files with 85 additions and 88 deletions

View File

@ -333,7 +333,7 @@ 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);
std::vector<texture_dimension_extended> td; std::vector<rsx::texture_dimension_extended> td;
RSXFragmentProgram prog; RSXFragmentProgram prog;
prog.size = 0, prog.addr = vm::base(ptr + vmprog.ucode), prog.offset = 0, prog.ctrl = ctrl; prog.size = 0, prog.addr = vm::base(ptr + vmprog.ucode), prog.offset = 0, prog.ctrl = ctrl;
GLFragmentDecompilerThread(m_glsl_shader, param_array, prog, size).Task(); GLFragmentDecompilerThread(m_glsl_shader, param_array, prog, size).Task();

View File

@ -130,16 +130,16 @@ std::string FragmentProgramDecompiler::AddTex()
std::string sampler; std::string sampler;
switch (m_prog.get_texture_dimension(dst.tex_num)) switch (m_prog.get_texture_dimension(dst.tex_num))
{ {
case texture_dimension_extended::texture_dimension_1d: case rsx::texture_dimension_extended::texture_dimension_1d:
sampler = "sampler1D"; sampler = "sampler1D";
break; break;
case texture_dimension_extended::texture_dimension_cubemap: case rsx::texture_dimension_extended::texture_dimension_cubemap:
sampler = "samplerCube"; sampler = "samplerCube";
break; break;
case texture_dimension_extended::texture_dimension_2d: case rsx::texture_dimension_extended::texture_dimension_2d:
sampler = "sampler2D"; sampler = "sampler2D";
break; break;
case texture_dimension_extended::texture_dimension_3d: case rsx::texture_dimension_extended::texture_dimension_3d:
sampler = "sampler3D"; sampler = "sampler3D";
break; break;
} }
@ -442,16 +442,16 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode)
case RSX_FP_OPCODE_TEX: case RSX_FP_OPCODE_TEX:
switch (m_prog.get_texture_dimension(dst.tex_num)) switch (m_prog.get_texture_dimension(dst.tex_num))
{ {
case texture_dimension_extended::texture_dimension_1d: case rsx::texture_dimension_extended::texture_dimension_1d:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE1D)); SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE1D));
return true; return true;
case texture_dimension_extended::texture_dimension_2d: case rsx::texture_dimension_extended::texture_dimension_2d:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D)); SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D));
return true; return true;
case texture_dimension_extended::texture_dimension_cubemap: case rsx::texture_dimension_extended::texture_dimension_cubemap:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE)); SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE));
return true; return true;
case texture_dimension_extended::texture_dimension_3d: case rsx::texture_dimension_extended::texture_dimension_3d:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE3D)); SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE3D));
return true; return true;
} }
@ -460,16 +460,16 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode)
case RSX_FP_OPCODE_TXP: case RSX_FP_OPCODE_TXP:
switch (m_prog.get_texture_dimension(dst.tex_num)) switch (m_prog.get_texture_dimension(dst.tex_num))
{ {
case texture_dimension_extended::texture_dimension_1d: case rsx::texture_dimension_extended::texture_dimension_1d:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_PROJ)); SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_PROJ));
return true; return true;
case texture_dimension_extended::texture_dimension_2d: case rsx::texture_dimension_extended::texture_dimension_2d:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_PROJ)); SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_PROJ));
return true; return true;
case texture_dimension_extended::texture_dimension_cubemap: case rsx::texture_dimension_extended::texture_dimension_cubemap:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_PROJ)); SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_PROJ));
return true; return true;
case texture_dimension_extended::texture_dimension_3d: case rsx::texture_dimension_extended::texture_dimension_3d:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_PROJ)); SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_PROJ));
return true; return true;
} }
@ -480,16 +480,16 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode)
case RSX_FP_OPCODE_TXL: case RSX_FP_OPCODE_TXL:
switch (m_prog.get_texture_dimension(dst.tex_num)) switch (m_prog.get_texture_dimension(dst.tex_num))
{ {
case texture_dimension_extended::texture_dimension_1d: case rsx::texture_dimension_extended::texture_dimension_1d:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_LOD)); SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_LOD));
return true; return true;
case texture_dimension_extended::texture_dimension_2d: case rsx::texture_dimension_extended::texture_dimension_2d:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_LOD)); SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_LOD));
return true; return true;
case texture_dimension_extended::texture_dimension_cubemap: case rsx::texture_dimension_extended::texture_dimension_cubemap:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_LOD)); SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_LOD));
return true; return true;
case texture_dimension_extended::texture_dimension_3d: case rsx::texture_dimension_extended::texture_dimension_3d:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_LOD)); SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_LOD));
return true; return true;
} }

View File

@ -116,32 +116,32 @@ u32 get_row_pitch_in_block(u16 width_in_block, size_t multiple_constraints_in_by
size_t divided = (width_in_block * sizeof(T) + multiple_constraints_in_byte - 1) / multiple_constraints_in_byte; size_t divided = (width_in_block * sizeof(T) + multiple_constraints_in_byte - 1) / multiple_constraints_in_byte;
return static_cast<u32>(divided * multiple_constraints_in_byte / sizeof(T)); return static_cast<u32>(divided * multiple_constraints_in_byte / sizeof(T));
} }
/**
* Since rsx ignore unused dimensionnality some app set them to 0.
* Use 1 value instead to be more general.
*/
std::tuple<u16, u16, u8> get_height_depth_layer(const rsx::texture &tex)
{
switch (tex.get_extended_texture_dimension())
{
case rsx::texture_dimension_extended::texture_dimension_1d: return std::make_tuple(1, 1, 1);
case rsx::texture_dimension_extended::texture_dimension_2d: return std::make_tuple(tex.height(), 1, 1);
case rsx::texture_dimension_extended::texture_dimension_cubemap: return std::make_tuple(tex.height(), 1, 6);
case rsx::texture_dimension_extended::texture_dimension_3d: return std::make_tuple(tex.height(), tex.depth(), 1);
}
throw EXCEPTION("Unsupported texture dimension");
}
} }
std::vector<rsx_subresource_layout> get_subresources_layout(const rsx::texture &texture) std::vector<rsx_subresource_layout> get_subresources_layout(const rsx::texture &texture)
{ {
u16 w = texture.width(), h = texture.height(); u16 w = texture.width();
u16 h;
u16 depth; u16 depth;
u8 layer; u8 layer;
if (texture.dimension() == rsx::texture_dimension::dimension1d) std::tie(h, depth, layer) = get_height_depth_layer(texture);
{
depth = 1;
layer = 1;
h = 1;
}
else if (texture.dimension() == rsx::texture_dimension::dimension2d)
{
depth = 1;
layer = texture.cubemap() ? 6 : 1;
}
else if (texture.dimension() == rsx::texture_dimension::dimension3d)
{
depth = texture.depth();
layer = 1;
}
else
throw EXCEPTION("Unsupported texture dimension %d", texture.dimension());
int format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); int format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);

View File

@ -47,18 +47,15 @@ namespace
const u8 format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); const u8 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);
if (texture.dimension() == rsx::texture_dimension::dimension1d) switch (texture.get_extended_texture_dimension())
{ {
case rsx::texture_dimension_extended::texture_dimension_1d:
return CD3DX12_RESOURCE_DESC::Tex1D(dxgi_format, texture.width(), 1, texture.get_exact_mipmap_count()); return CD3DX12_RESOURCE_DESC::Tex1D(dxgi_format, texture.width(), 1, texture.get_exact_mipmap_count());
} case rsx::texture_dimension_extended::texture_dimension_2d:
else if (texture.dimension() == rsx::texture_dimension::dimension2d) return CD3DX12_RESOURCE_DESC::Tex2D(dxgi_format, texture.width(), texture.height(), 1, texture.get_exact_mipmap_count());
{ case rsx::texture_dimension_extended::texture_dimension_cubemap:
// if (texture.depth() < 2); return CD3DX12_RESOURCE_DESC::Tex2D(dxgi_format, texture.width(), texture.height(), 6, texture.get_exact_mipmap_count());
size_t depth = (texture.cubemap()) ? 6 : 1; case rsx::texture_dimension_extended::texture_dimension_3d:
return CD3DX12_RESOURCE_DESC::Tex2D(dxgi_format, texture.width(), texture.height(), (UINT)depth, texture.get_exact_mipmap_count());
}
else if (texture.dimension() == rsx::texture_dimension::dimension3d)
{
return CD3DX12_RESOURCE_DESC::Tex3D(dxgi_format, texture.width(), texture.height(), texture.depth(), texture.get_exact_mipmap_count()); return CD3DX12_RESOURCE_DESC::Tex3D(dxgi_format, texture.width(), texture.height(), texture.depth(), texture.get_exact_mipmap_count());
} }
throw EXCEPTION("Unknow texture dimension"); throw EXCEPTION("Unknow texture dimension");
@ -146,31 +143,26 @@ ComPtr<ID3D12Resource> upload_single_texture(
D3D12_SHADER_RESOURCE_VIEW_DESC get_srv_descriptor_with_dimensions(const rsx::texture &tex) D3D12_SHADER_RESOURCE_VIEW_DESC get_srv_descriptor_with_dimensions(const rsx::texture &tex)
{ {
D3D12_SHADER_RESOURCE_VIEW_DESC shared_resource_view_desc = {}; D3D12_SHADER_RESOURCE_VIEW_DESC shared_resource_view_desc = {};
if (tex.dimension() == rsx::texture_dimension::dimension1d) switch (tex.get_extended_texture_dimension())
{ {
case rsx::texture_dimension_extended::texture_dimension_1d:
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D; shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D;
shared_resource_view_desc.Texture1D.MipLevels = tex.get_exact_mipmap_count(); shared_resource_view_desc.Texture1D.MipLevels = tex.get_exact_mipmap_count();
return shared_resource_view_desc; return shared_resource_view_desc;
} case rsx::texture_dimension_extended::texture_dimension_2d:
if (tex.dimension() == rsx::texture_dimension::dimension2d)
{
if (tex.cubemap())
{
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
shared_resource_view_desc.TextureCube.MipLevels = tex.get_exact_mipmap_count();
return shared_resource_view_desc;
}
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
shared_resource_view_desc.Texture2D.MipLevels = tex.get_exact_mipmap_count(); shared_resource_view_desc.Texture2D.MipLevels = tex.get_exact_mipmap_count();
return shared_resource_view_desc; return shared_resource_view_desc;
} case rsx::texture_dimension_extended::texture_dimension_cubemap:
if (tex.dimension() == rsx::texture_dimension::dimension3d) shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
{ shared_resource_view_desc.TextureCube.MipLevels = tex.get_exact_mipmap_count();
return shared_resource_view_desc;
case rsx::texture_dimension_extended::texture_dimension_3d:
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D; shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D;
shared_resource_view_desc.Texture3D.MipLevels = tex.get_exact_mipmap_count(); shared_resource_view_desc.Texture3D.MipLevels = tex.get_exact_mipmap_count();
return shared_resource_view_desc; return shared_resource_view_desc;
} }
throw EXCEPTION("Wrong texture dimension %d", tex.dimension()); throw EXCEPTION("Wrong texture dimension");
} }
} }

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "GCM.h" #include "GCM.h"
#include "RSXTexture.h"
enum enum
{ {
@ -205,18 +206,6 @@ static const std::string rsx_fp_op_names[] =
"NULL", "BRK", "CAL", "IFE", "LOOP", "REP", "RET" "NULL", "BRK", "CAL", "IFE", "LOOP", "REP", "RET"
}; };
/**
* Use an extra cubemap format
*/
enum class texture_dimension_extended : u8
{
texture_dimension_1d = 0,
texture_dimension_2d = 1,
texture_dimension_cubemap = 2,
texture_dimension_3d = 3,
};
struct RSXFragmentProgram struct RSXFragmentProgram
{ {
u32 size; u32 size;
@ -234,15 +223,15 @@ struct RSXFragmentProgram
rsx::fog_mode fog_equation; rsx::fog_mode fog_equation;
u16 height; u16 height;
texture_dimension_extended get_texture_dimension(u8 id) const rsx::texture_dimension_extended get_texture_dimension(u8 id) const
{ {
return (texture_dimension_extended)((texture_dimensions >> (id * 2)) & 0x3); return (rsx::texture_dimension_extended)((texture_dimensions >> (id * 2)) & 0x3);
} }
void set_texture_dimension(const std::array<texture_dimension_extended, 16> &dimensions) void set_texture_dimension(const std::array<rsx::texture_dimension_extended, 16> &dimensions)
{ {
size_t id = 0; size_t id = 0;
for (const texture_dimension_extended &dim : dimensions) for (const rsx::texture_dimension_extended &dim : dimensions)
{ {
texture_dimensions &= ~(0x3 << (id * 2)); texture_dimensions &= ~(0x3 << (id * 2));
u8 d = (u8)dim; u8 d = (u8)dim;

View File

@ -65,6 +65,16 @@ namespace rsx
return rsx::to_texture_dimension((method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 4) & 0xf); return rsx::to_texture_dimension((method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 4) & 0xf);
} }
rsx::texture_dimension_extended texture::get_extended_texture_dimension() const
{
switch (dimension())
{
case rsx::texture_dimension::dimension1d: return rsx::texture_dimension_extended::texture_dimension_1d;
case rsx::texture_dimension::dimension3d: return rsx::texture_dimension_extended::texture_dimension_2d;
case rsx::texture_dimension::dimension2d: return cubemap() ? rsx::texture_dimension_extended::texture_dimension_cubemap : rsx::texture_dimension_extended::texture_dimension_2d;
}
}
u8 texture::format() const u8 texture::format() const
{ {
return ((method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 8) & 0xff); return ((method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 8) & 0xff);

View File

@ -3,6 +3,17 @@
namespace rsx namespace rsx
{ {
/**
* Use an extra cubemap format
*/
enum class texture_dimension_extended : u8
{
texture_dimension_1d = 0,
texture_dimension_2d = 1,
texture_dimension_cubemap = 2,
texture_dimension_3d = 3,
};
class texture class texture
{ {
protected: protected:
@ -20,6 +31,12 @@ namespace rsx
bool cubemap() const; bool cubemap() const;
u8 border_type() const; u8 border_type() const;
rsx::texture_dimension dimension() const; rsx::texture_dimension dimension() const;
/**
* 2d texture can be either plane or cubemap texture depending on cubemap bit.
* Since cubemap is a format per se in all gfx API this function directly returns
* cubemap as a separate dimension.
*/
rsx::texture_dimension_extended get_extended_texture_dimension() const;
u8 format() const; u8 format() const;
bool is_compressed_format() const; bool is_compressed_format() const;
u16 mipmap() const; u16 mipmap() const;

View File

@ -724,19 +724,8 @@ namespace rsx
{ {
if (!textures[i].enabled()) if (!textures[i].enabled())
texture_dimensions[i] = texture_dimension_extended::texture_dimension_2d; texture_dimensions[i] = texture_dimension_extended::texture_dimension_2d;
else if (textures[i].dimension() == rsx::texture_dimension::dimension1d)
texture_dimensions[i] = texture_dimension_extended::texture_dimension_1d;
else if (textures[i].dimension() == rsx::texture_dimension::dimension2d)
{
if (textures[i].cubemap())
texture_dimensions[i] = texture_dimension_extended::texture_dimension_cubemap;
else
texture_dimensions[i] = texture_dimension_extended::texture_dimension_2d;
}
else if (textures[i].dimension() == rsx::texture_dimension::dimension3d)
texture_dimensions[i] = texture_dimension_extended::texture_dimension_3d;
else else
throw EXCEPTION("Unable to determine texture dimension"); texture_dimensions[i] = textures[i].get_extended_texture_dimension();
if (textures[i].enabled() && (textures[i].format() & CELL_GCM_TEXTURE_UN)) if (textures[i].enabled() && (textures[i].format() & CELL_GCM_TEXTURE_UN))
result.unnormalized_coords |= (1 << i); result.unnormalized_coords |= (1 << i);
} }