mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-21 03:16:54 +02:00
clean up graphics helpers
This commit is contained in:
@@ -46,8 +46,8 @@ vk::PipelineStageFlags ShaderPipelineStages(vk::ShaderStageFlags stages) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanMemoryBarrier MakeShaderWriteDependency() {
|
vk::MemoryBarrier MakeShaderWriteDependency() {
|
||||||
VulkanMemoryBarrier barrier {};
|
vk::MemoryBarrier barrier {};
|
||||||
barrier.srcAccessMask = vk::AccessFlagBits::eShaderWrite;
|
barrier.srcAccessMask = vk::AccessFlagBits::eShaderWrite;
|
||||||
barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite |
|
barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite |
|
||||||
vk::AccessFlagBits::eVertexAttributeRead |
|
vk::AccessFlagBits::eVertexAttributeRead |
|
||||||
@@ -58,15 +58,15 @@ VulkanMemoryBarrier MakeShaderWriteDependency() {
|
|||||||
return barrier;
|
return barrier;
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanMemoryBarrier MakeShaderAccessDependency() {
|
vk::MemoryBarrier MakeShaderAccessDependency() {
|
||||||
VulkanMemoryBarrier barrier {};
|
vk::MemoryBarrier barrier {};
|
||||||
barrier.srcAccessMask = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite;
|
barrier.srcAccessMask = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite;
|
||||||
barrier.dstAccessMask = vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite;
|
barrier.dstAccessMask = vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite;
|
||||||
return barrier;
|
return barrier;
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanMemoryBarrier MakeShaderWriteHazardDependency() {
|
vk::MemoryBarrier MakeShaderWriteHazardDependency() {
|
||||||
VulkanMemoryBarrier barrier {};
|
vk::MemoryBarrier barrier {};
|
||||||
barrier.srcAccessMask = vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite;
|
barrier.srcAccessMask = vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite;
|
||||||
barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite;
|
barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite;
|
||||||
return barrier;
|
return barrier;
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ struct ShaderStageRuntime;
|
|||||||
|
|
||||||
vk::ShaderStageFlagBits NativeShaderStage(ShaderType stage);
|
vk::ShaderStageFlagBits NativeShaderStage(ShaderType stage);
|
||||||
vk::PipelineStageFlags ShaderPipelineStages(vk::ShaderStageFlags stages);
|
vk::PipelineStageFlags ShaderPipelineStages(vk::ShaderStageFlags stages);
|
||||||
VulkanMemoryBarrier MakeShaderAccessDependency();
|
vk::MemoryBarrier MakeShaderAccessDependency();
|
||||||
VulkanMemoryBarrier MakeShaderWriteHazardDependency();
|
vk::MemoryBarrier MakeShaderWriteHazardDependency();
|
||||||
VulkanMemoryBarrier MakeShaderWriteDependency();
|
vk::MemoryBarrier MakeShaderWriteDependency();
|
||||||
vk::BufferMemoryBarrier MakeGdsDependency(vk::Buffer buffer);
|
vk::BufferMemoryBarrier MakeGdsDependency(vk::Buffer buffer);
|
||||||
bool HasShaderBufferWrites(const ShaderStageRuntime& runtime);
|
bool HasShaderBufferWrites(const ShaderStageRuntime& runtime);
|
||||||
void ShaderAccessBarrier(vk::CommandBuffer vk_buffer, vk::PipelineStageFlags source_stages);
|
void ShaderAccessBarrier(vk::CommandBuffer vk_buffer, vk::PipelineStageFlags source_stages);
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ void RenderExecutor::DispatchDirect(uint64_t submit_id, CommandBuffer& buffer,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ShaderAddressValid(sh_ctx.GetCs().cs_regs.data_addr)) {
|
if (sh_ctx.GetCs().cs_regs.data_addr == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -421,7 +421,7 @@ static void SetGraphicsDynamicParams(const CommandBuffer& buffer, vk::CommandBuf
|
|||||||
static bool DrawHasValidVertexShader(const HW::Shader& sh_ctx) {
|
static bool DrawHasValidVertexShader(const HW::Shader& sh_ctx) {
|
||||||
|
|
||||||
const auto& vs = sh_ctx.GetVs();
|
const auto& vs = sh_ctx.GetVs();
|
||||||
return ShaderAddressValid(vs.es_regs.data_addr);
|
return vs.es_regs.data_addr != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool PixelShaderHasDepthOrCoverageSideEffects(const HW::ShaderRegisters& sh_regs) {
|
static bool PixelShaderHasDepthOrCoverageSideEffects(const HW::ShaderRegisters& sh_regs) {
|
||||||
@@ -608,7 +608,7 @@ static bool DrawHasActivePixelShader(const CommandBuffer& buffer) {
|
|||||||
const auto& ctx = buffer.GetRegisters();
|
const auto& ctx = buffer.GetRegisters();
|
||||||
const auto& sh_regs = ctx.GetShaderRegisters();
|
const auto& sh_regs = ctx.GetShaderRegisters();
|
||||||
const bool has_color_output = (ctx.GetRenderTargetMask() & sh_regs.m_cbShaderMask) != 0;
|
const bool has_color_output = (ctx.GetRenderTargetMask() & sh_regs.m_cbShaderMask) != 0;
|
||||||
return ShaderAddressValid(buffer.GetShaders().GetPs().ps_regs.data_addr) &&
|
return buffer.GetShaders().GetPs().ps_regs.data_addr != 0 &&
|
||||||
(has_color_output || PixelShaderHasDepthOrCoverageSideEffects(sh_regs));
|
(has_color_output || PixelShaderHasDepthOrCoverageSideEffects(sh_regs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,6 @@
|
|||||||
|
|
||||||
namespace Libs::Graphics {
|
namespace Libs::Graphics {
|
||||||
|
|
||||||
using VulkanMemoryBarrier = vk::MemoryBarrier;
|
|
||||||
|
|
||||||
vk::Format VulkanFormat(Prospero::BufferFormat guest_format);
|
vk::Format VulkanFormat(Prospero::BufferFormat guest_format);
|
||||||
void RequireVulkanSuccess(vk::Result result, const char* operation);
|
void RequireVulkanSuccess(vk::Result result, const char* operation);
|
||||||
vk::ShaderModule CompileSPV(std::span<const uint32_t> code, vk::Device device);
|
vk::ShaderModule CompileSPV(std::span<const uint32_t> code, vk::Device device);
|
||||||
|
|||||||
@@ -22,9 +22,6 @@
|
|||||||
|
|
||||||
// IWYU pragma: no_include <intrin.h>
|
// IWYU pragma: no_include <intrin.h>
|
||||||
|
|
||||||
#define KYTY_ENABLE_DEBUG_PRINTF
|
|
||||||
#define KYTY_DBG_INPUT
|
|
||||||
|
|
||||||
namespace Libs::Graphics {
|
namespace Libs::Graphics {
|
||||||
|
|
||||||
struct Presenter::Frame {
|
struct Presenter::Frame {
|
||||||
|
|||||||
@@ -49,7 +49,6 @@
|
|||||||
// IWYU pragma: no_include <intrin.h>
|
// IWYU pragma: no_include <intrin.h>
|
||||||
|
|
||||||
#define KYTY_ENABLE_DEBUG_PRINTF
|
#define KYTY_ENABLE_DEBUG_PRINTF
|
||||||
#define KYTY_DBG_INPUT
|
|
||||||
|
|
||||||
namespace Libs::Graphics {
|
namespace Libs::Graphics {
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,6 @@
|
|||||||
|
|
||||||
// IWYU pragma: no_include <intrin.h>
|
// IWYU pragma: no_include <intrin.h>
|
||||||
|
|
||||||
#define KYTY_ENABLE_DEBUG_PRINTF
|
|
||||||
#define KYTY_DBG_INPUT
|
#define KYTY_DBG_INPUT
|
||||||
|
|
||||||
namespace Libs::Graphics {
|
namespace Libs::Graphics {
|
||||||
@@ -180,12 +179,6 @@ struct EventDisplay {
|
|||||||
DisplayOrientation orientation;
|
DisplayOrientation orientation;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr uint32_t KYTY_SDL_BUTTON_LMASK = SDL_BUTTON_LMASK; // NOLINT(hicpp-signed-bitwise)
|
|
||||||
constexpr uint32_t KYTY_SDL_BUTTON_MMASK = SDL_BUTTON_MMASK; // NOLINT(hicpp-signed-bitwise)
|
|
||||||
constexpr uint32_t KYTY_SDL_BUTTON_RMASK = SDL_BUTTON_RMASK; // NOLINT(hicpp-signed-bitwise)
|
|
||||||
constexpr uint32_t KYTY_SDL_BUTTON_X1MASK = SDL_BUTTON_X1MASK; // NOLINT(hicpp-signed-bitwise)
|
|
||||||
constexpr uint32_t KYTY_SDL_BUTTON_X2MASK = SDL_BUTTON_X2MASK; // NOLINT(hicpp-signed-bitwise)
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
std::unique_ptr<WindowContext> g_window;
|
std::unique_ptr<WindowContext> g_window;
|
||||||
@@ -193,7 +186,6 @@ std::unique_ptr<WindowContext> g_window;
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
constexpr const char* KYTY_SDL_WINDOW_CAPTION = "Game";
|
constexpr const char* KYTY_SDL_WINDOW_CAPTION = "Game";
|
||||||
constexpr int KYTY_SDL_WINDOWPOS_CENTERED = SDL_WINDOWPOS_CENTERED; /*NOLINT(hicpp-signed-bitwise)*/
|
|
||||||
|
|
||||||
static void SetPause(WindowLoopState& game, bool flag) {
|
static void SetPause(WindowLoopState& game, bool flag) {
|
||||||
LOGF("Pause: %s\n", flag ? "true" : "false");
|
LOGF("Pause: %s\n", flag ? "true" : "false");
|
||||||
@@ -614,11 +606,11 @@ void WindowContext::ProcessEvent(double time_s) {
|
|||||||
|
|
||||||
mb.down = false;
|
mb.down = false;
|
||||||
mb.up = false;
|
mb.up = false;
|
||||||
mb.left = ((event->motion.state & KYTY_SDL_BUTTON_LMASK) != 0u);
|
mb.left = ((event->motion.state & SDL_BUTTON_LMASK) != 0u);
|
||||||
mb.middle = ((event->motion.state & KYTY_SDL_BUTTON_MMASK) != 0u);
|
mb.middle = ((event->motion.state & SDL_BUTTON_MMASK) != 0u);
|
||||||
mb.right = ((event->motion.state & KYTY_SDL_BUTTON_RMASK) != 0u);
|
mb.right = ((event->motion.state & SDL_BUTTON_RMASK) != 0u);
|
||||||
mb.x1 = ((event->motion.state & KYTY_SDL_BUTTON_X1MASK) != 0u);
|
mb.x1 = ((event->motion.state & SDL_BUTTON_X1MASK) != 0u);
|
||||||
mb.x2 = ((event->motion.state & KYTY_SDL_BUTTON_X2MASK) != 0u);
|
mb.x2 = ((event->motion.state & SDL_BUTTON_X2MASK) != 0u);
|
||||||
mb.touch = (event->motion.which == SDL_TOUCH_MOUSEID);
|
mb.touch = (event->motion.which == SDL_TOUCH_MOUSEID);
|
||||||
mb.pressed = false;
|
mb.pressed = false;
|
||||||
mb.released = false;
|
mb.released = false;
|
||||||
@@ -868,8 +860,8 @@ static void WindowCreate(WindowContext& context) {
|
|||||||
window_flags |= static_cast<uint32_t>(SDL_WINDOW_BORDERLESS);
|
window_flags |= static_cast<uint32_t>(SDL_WINDOW_BORDERLESS);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
context.window = SDL_CreateWindow(KYTY_SDL_WINDOW_CAPTION, KYTY_SDL_WINDOWPOS_CENTERED,
|
context.window = SDL_CreateWindow(KYTY_SDL_WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED,
|
||||||
KYTY_SDL_WINDOWPOS_CENTERED, width, height, window_flags);
|
SDL_WINDOWPOS_CENTERED, width, height, window_flags);
|
||||||
|
|
||||||
if (context.window == nullptr) {
|
if (context.window == nullptr) {
|
||||||
EXIT("%s\n", SDL_GetError());
|
EXIT("%s\n", SDL_GetError());
|
||||||
|
|||||||
@@ -105,8 +105,6 @@ void ClearEmbeddedFetchVectorLanes(EmbeddedFetchVectorLanes* lanes, uint32_t reg
|
|||||||
lanes->erase(first, last);
|
lanes->erase(first, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
using EmbeddedFetchData = Frontend::EmbeddedFetchPlan;
|
|
||||||
|
|
||||||
bool IsDecodedSgpr(const Decoder::Operand& op) {
|
bool IsDecodedSgpr(const Decoder::Operand& op) {
|
||||||
return op.kind == Decoder::OperandKind::Sgpr || op.kind == Decoder::OperandKind::VccLo ||
|
return op.kind == Decoder::OperandKind::Sgpr || op.kind == Decoder::OperandKind::VccLo ||
|
||||||
op.kind == Decoder::OperandKind::VccHi;
|
op.kind == Decoder::OperandKind::VccHi;
|
||||||
@@ -210,13 +208,12 @@ int BufferTableAttribFromOffset(uint32_t raw_offset, int dword) {
|
|||||||
return static_cast<int>((raw_offset + static_cast<uint32_t>(dword) * 4u) / 16u);
|
return static_cast<int>((raw_offset + static_cast<uint32_t>(dword) * 4u) / 16u);
|
||||||
}
|
}
|
||||||
|
|
||||||
EmbeddedFetchData DetectEmbeddedVertexFetch(const Decoder::Program& decoded,
|
Frontend::EmbeddedFetchPlan DetectEmbeddedVertexFetch(
|
||||||
const ShaderVertexInputInfo* input_info,
|
const Decoder::Program& decoded, const ShaderVertexInputInfo* input_info,
|
||||||
uint32_t user_data_base, uint32_t user_data_count,
|
uint32_t user_data_base, uint32_t user_data_count, uint32_t wave_size) {
|
||||||
uint32_t wave_size) {
|
|
||||||
const uint32_t vertex_index_reg = input_info->logical_stage == ShaderType::Local ? 2u : 5u;
|
const uint32_t vertex_index_reg = input_info->logical_stage == ShaderType::Local ? 2u : 5u;
|
||||||
const uint32_t instance_index_reg = input_info->logical_stage == ShaderType::Local ? 5u : 8u;
|
const uint32_t instance_index_reg = input_info->logical_stage == ShaderType::Local ? 5u : 8u;
|
||||||
EmbeddedFetchData data;
|
Frontend::EmbeddedFetchPlan data;
|
||||||
data.loads.reserve(input_info->resources_num);
|
data.loads.reserve(input_info->resources_num);
|
||||||
int32_t vertex_offset_candidate = -1;
|
int32_t vertex_offset_candidate = -1;
|
||||||
int32_t instance_offset_candidate = -1;
|
int32_t instance_offset_candidate = -1;
|
||||||
@@ -560,7 +557,7 @@ TranslateResult TranslateProgram(std::span<const uint32_t> code, const CompileOp
|
|||||||
static_cast<uint64_t>(cfg.natural_loops.size()), phase_ms());
|
static_cast<uint64_t>(cfg.natural_loops.size()), phase_ms());
|
||||||
}
|
}
|
||||||
|
|
||||||
EmbeddedFetchData embedded_fetch;
|
Frontend::EmbeddedFetchPlan embedded_fetch;
|
||||||
if ((options.stage == ShaderType::Vertex || options.stage == ShaderType::Local) &&
|
if ((options.stage == ShaderType::Vertex || options.stage == ShaderType::Local) &&
|
||||||
options.input_info.vertex != nullptr && options.input_info.vertex->fetch_embedded) {
|
options.input_info.vertex != nullptr && options.input_info.vertex->fetch_embedded) {
|
||||||
embedded_fetch = DetectEmbeddedVertexFetch(
|
embedded_fetch = DetectEmbeddedVertexFetch(
|
||||||
|
|||||||
@@ -308,8 +308,6 @@ uint32_t ConstantI32(EmitterState& state, int32_t value);
|
|||||||
|
|
||||||
uint32_t ConstantF32(EmitterState& state, uint32_t bits);
|
uint32_t ConstantF32(EmitterState& state, uint32_t bits);
|
||||||
|
|
||||||
uint32_t FloatBits(float value);
|
|
||||||
|
|
||||||
uint32_t ConstantF32Value(EmitterState& state, float value);
|
uint32_t ConstantF32Value(EmitterState& state, float value);
|
||||||
|
|
||||||
uint32_t ConstantBool(EmitterState& state, bool value);
|
uint32_t ConstantBool(EmitterState& state, bool value);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "graphics/shader/recompiler/backend/spirv/spirvEmitterInternal.h"
|
#include "graphics/shader/recompiler/backend/spirv/spirvEmitterInternal.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <bit>
|
||||||
|
|
||||||
namespace Libs::Graphics::ShaderRecompiler::Spirv::Emitter {
|
namespace Libs::Graphics::ShaderRecompiler::Spirv::Emitter {
|
||||||
|
|
||||||
@@ -256,14 +257,8 @@ uint32_t ConstantF32(EmitterState& state, uint32_t bits) {
|
|||||||
return state.builder.Constant(spv::OpConstant, TypeF32(state), bits);
|
return state.builder.Constant(spv::OpConstant, TypeF32(state), bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t FloatBits(float value) {
|
|
||||||
uint32_t bits = 0;
|
|
||||||
std::memcpy(&bits, &value, sizeof(bits));
|
|
||||||
return bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t ConstantF32Value(EmitterState& state, float value) {
|
uint32_t ConstantF32Value(EmitterState& state, float value) {
|
||||||
return ConstantF32(state, FloatBits(value));
|
return ConstantF32(state, std::bit_cast<uint32_t>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ConstantBool(EmitterState& state, bool value) {
|
uint32_t ConstantBool(EmitterState& state, bool value) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "graphics/shader/recompiler/frontend/decode/OpcodeTable.h"
|
#include "graphics/shader/recompiler/frontend/decode/OpcodeTable.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <bit>
|
||||||
|
|
||||||
namespace Libs::Graphics::ShaderRecompiler::Decoder {
|
namespace Libs::Graphics::ShaderRecompiler::Decoder {
|
||||||
namespace {
|
namespace {
|
||||||
@@ -203,18 +204,6 @@ constexpr auto MIMG_SAMPLE_OPS = Detail::MakeOpcodeTable<0x100>(MIMG_SAMPLE_OPCO
|
|||||||
constexpr auto MIMG_GATHER_OPS = Detail::MakeOpcodeTable<0x100>(MIMG_GATHER_OPCODE_LIST);
|
constexpr auto MIMG_GATHER_OPS = Detail::MakeOpcodeTable<0x100>(MIMG_GATHER_OPCODE_LIST);
|
||||||
constexpr auto MIMG_ATOMIC_OPS = Detail::MakeOpcodeTable<0x100>(MIMG_ATOMIC_OPCODE_LIST);
|
constexpr auto MIMG_ATOMIC_OPS = Detail::MakeOpcodeTable<0x100>(MIMG_ATOMIC_OPCODE_LIST);
|
||||||
|
|
||||||
const MimgSampleInfo* LookupSample(uint32_t opcode) {
|
|
||||||
return Detail::FindOpcode(MIMG_SAMPLE_OPS, opcode);
|
|
||||||
}
|
|
||||||
|
|
||||||
const MimgGatherInfo* LookupGather(uint32_t opcode) {
|
|
||||||
return Detail::FindOpcode(MIMG_GATHER_OPS, opcode);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Detail::OpcodeMap* LookupAtomic(uint32_t opcode) {
|
|
||||||
return Detail::FindOpcode(MIMG_ATOMIC_OPS, opcode);
|
|
||||||
}
|
|
||||||
|
|
||||||
Opcode DecodeMimgOpcode(uint32_t opcode, const MimgSampleInfo* sample, const MimgGatherInfo* gather,
|
Opcode DecodeMimgOpcode(uint32_t opcode, const MimgSampleInfo* sample, const MimgGatherInfo* gather,
|
||||||
const Detail::OpcodeMap* atomic) {
|
const Detail::OpcodeMap* atomic) {
|
||||||
if (sample != nullptr) {
|
if (sample != nullptr) {
|
||||||
@@ -280,10 +269,6 @@ uint32_t CountDmaskComponents(uint32_t dmask) {
|
|||||||
return count != 0 ? count : 1u;
|
return count != 0 ? count : 1u;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsSingleDmaskBit(uint32_t dmask) {
|
|
||||||
return dmask != 0u && (dmask & (dmask - 1u)) == 0u;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ImageAddressComponent ImageAddressComponentLayout(uint32_t flags, uint32_t component) {
|
ImageAddressComponent ImageAddressComponentLayout(uint32_t flags, uint32_t component) {
|
||||||
@@ -332,9 +317,9 @@ void DecodeMimg(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
|
|||||||
const bool r128 = ((word0 >> 15u) & 0x1u) != 0u;
|
const bool r128 = ((word0 >> 15u) & 0x1u) != 0u;
|
||||||
const bool a16 = ((word1 >> 30u) & 0x1u) != 0u;
|
const bool a16 = ((word1 >> 30u) & 0x1u) != 0u;
|
||||||
const bool d16 = ((word1 >> 31u) & 0x1u) != 0u;
|
const bool d16 = ((word1 >> 31u) & 0x1u) != 0u;
|
||||||
const auto* sample = LookupSample(opcode);
|
const auto* sample = Detail::FindOpcode(MIMG_SAMPLE_OPS, opcode);
|
||||||
const auto* gather = LookupGather(opcode);
|
const auto* gather = Detail::FindOpcode(MIMG_GATHER_OPS, opcode);
|
||||||
const auto* atomic = LookupAtomic(opcode);
|
const auto* atomic = Detail::FindOpcode(MIMG_ATOMIC_OPS, opcode);
|
||||||
|
|
||||||
inst.pc = pc;
|
inst.pc = pc;
|
||||||
inst.word_count = word_count;
|
inst.word_count = word_count;
|
||||||
@@ -364,7 +349,7 @@ void DecodeMimg(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
|
|||||||
if (inst.opcode == Opcode::UNSUPPORTED) {
|
if (inst.opcode == Opcode::UNSUPPORTED) {
|
||||||
SetUnsupported(inst, Family::MIMG, opcode, "MIMG opcode is not implemented");
|
SetUnsupported(inst, Family::MIMG, opcode, "MIMG opcode is not implemented");
|
||||||
}
|
}
|
||||||
if (gather != nullptr && !IsSingleDmaskBit(inst.dmask)) {
|
if (gather != nullptr && !std::has_single_bit(inst.dmask)) {
|
||||||
SetUnsupported(inst, Family::MIMG, opcode,
|
SetUnsupported(inst, Family::MIMG, opcode,
|
||||||
"MIMG image gather requires exactly one dmask bit");
|
"MIMG image gather requires exactly one dmask bit");
|
||||||
}
|
}
|
||||||
@@ -382,7 +367,7 @@ void DecodeMimg(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char* MimgSampleOpcodeName(uint32_t opcode) {
|
const char* MimgSampleOpcodeName(uint32_t opcode) {
|
||||||
const auto* sample = LookupSample(opcode);
|
const auto* sample = Detail::FindOpcode(MIMG_SAMPLE_OPS, opcode);
|
||||||
return sample != nullptr ? sample->name : nullptr;
|
return sample != nullptr ? sample->name : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,10 +14,6 @@
|
|||||||
namespace Libs::Graphics::ShaderRecompiler::Decoder {
|
namespace Libs::Graphics::ShaderRecompiler::Decoder {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
uint32_t FloatBits(float value) {
|
|
||||||
return std::bit_cast<uint32_t>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HasLiteral(const Instruction& inst) {
|
bool HasLiteral(const Instruction& inst) {
|
||||||
return inst.src0.kind == OperandKind::LiteralConstant ||
|
return inst.src0.kind == OperandKind::LiteralConstant ||
|
||||||
inst.src1.kind == OperandKind::LiteralConstant ||
|
inst.src1.kind == OperandKind::LiteralConstant ||
|
||||||
@@ -242,7 +238,7 @@ void DecodeScalarSource(uint32_t code, uint32_t pc, Operand& operand) {
|
|||||||
if (code >= 240u && code <= 247u) {
|
if (code >= 240u && code <= 247u) {
|
||||||
constexpr float values[] = {0.5f, -0.5f, 1.0f, -1.0f, 2.0f, -2.0f, 4.0f, -4.0f};
|
constexpr float values[] = {0.5f, -0.5f, 1.0f, -1.0f, 2.0f, -2.0f, 4.0f, -4.0f};
|
||||||
operand.kind = OperandKind::FloatInlineConstant;
|
operand.kind = OperandKind::FloatInlineConstant;
|
||||||
operand.value = FloatBits(values[code - 240u]);
|
operand.value = std::bit_cast<uint32_t>(values[code - 240u]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (code >= 256u && code <= 511u) {
|
if (code >= 256u && code <= 511u) {
|
||||||
@@ -260,7 +256,7 @@ void DecodeScalarSource(uint32_t code, uint32_t pc, Operand& operand) {
|
|||||||
case 239u: operand.kind = OperandKind::PopsExitingWaveId; return;
|
case 239u: operand.kind = OperandKind::PopsExitingWaveId; return;
|
||||||
case 248u:
|
case 248u:
|
||||||
operand.kind = OperandKind::FloatInlineConstant;
|
operand.kind = OperandKind::FloatInlineConstant;
|
||||||
operand.value = FloatBits(0.15915494309189535f);
|
operand.value = std::bit_cast<uint32_t>(0.15915494309189535f);
|
||||||
return;
|
return;
|
||||||
case 251u: operand.kind = OperandKind::VccZ; return;
|
case 251u: operand.kind = OperandKind::VccZ; return;
|
||||||
case 252u: operand.kind = OperandKind::ExecZ; return;
|
case 252u: operand.kind = OperandKind::ExecZ; return;
|
||||||
|
|||||||
@@ -83,10 +83,6 @@ constexpr Vop2OpcodeInfo VOP2_OPCODE_LIST[] = {
|
|||||||
|
|
||||||
constexpr auto VOP2_OPS = Detail::MakeOpcodeTable<0x40>(VOP2_OPCODE_LIST);
|
constexpr auto VOP2_OPS = Detail::MakeOpcodeTable<0x40>(VOP2_OPCODE_LIST);
|
||||||
|
|
||||||
constexpr Opcode LookupVop2Opcode(uint32_t encoding) {
|
|
||||||
return Detail::LookupOpcode(VOP2_OPS, encoding);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr OpcodeMap VOP1_OPCODE_LIST[] = {
|
constexpr OpcodeMap VOP1_OPCODE_LIST[] = {
|
||||||
{0x00u, Opcode::V_NOP},
|
{0x00u, Opcode::V_NOP},
|
||||||
{0x01u, Opcode::V_MOV_B32},
|
{0x01u, Opcode::V_MOV_B32},
|
||||||
@@ -375,7 +371,7 @@ Opcode LookupVop3Opcode(uint32_t opcode) {
|
|||||||
if (IsUnsupportedVop3EncodedVop2Alias(opcode - 0x100u)) {
|
if (IsUnsupportedVop3EncodedVop2Alias(opcode - 0x100u)) {
|
||||||
return Opcode::UNSUPPORTED;
|
return Opcode::UNSUPPORTED;
|
||||||
}
|
}
|
||||||
return LookupVop2Opcode(opcode - 0x100u);
|
return Detail::LookupOpcode(VOP2_OPS, opcode - 0x100u);
|
||||||
}
|
}
|
||||||
if (opcode >= 0x180u && opcode <= 0x1ffu) {
|
if (opcode >= 0x180u && opcode <= 0x1ffu) {
|
||||||
return Detail::LookupOpcode(VOP3_ENCODED_VOP1_OPS, opcode - 0x180u);
|
return Detail::LookupOpcode(VOP3_ENCODED_VOP1_OPS, opcode - 0x180u);
|
||||||
@@ -1470,7 +1466,7 @@ void DecodeVop2(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
|
|||||||
inst.pc = pc;
|
inst.pc = pc;
|
||||||
inst.family = Family::VOP2;
|
inst.family = Family::VOP2;
|
||||||
inst.opcode_id = opcode;
|
inst.opcode_id = opcode;
|
||||||
inst.opcode = LookupVop2Opcode(opcode);
|
inst.opcode = Detail::LookupOpcode(VOP2_OPS, opcode);
|
||||||
SetRawWords(inst, code, word_index, 1);
|
SetRawWords(inst, code, word_index, 1);
|
||||||
|
|
||||||
if (inst.opcode == Opcode::UNSUPPORTED) {
|
if (inst.opcode == Opcode::UNSUPPORTED) {
|
||||||
|
|||||||
@@ -479,8 +479,6 @@ private:
|
|||||||
return std::bit_cast<float>(static_cast<uint32_t>(bits));
|
return std::bit_cast<float>(static_cast<uint32_t>(bits));
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t Float32Bits(float value) { return std::bit_cast<uint32_t>(value); }
|
|
||||||
|
|
||||||
bool EvaluateWide(Value value, uint64_t& result) {
|
bool EvaluateWide(Value value, uint64_t& result) {
|
||||||
value = value.Resolve();
|
value = value.Resolve();
|
||||||
if (value.IsImmediate()) {
|
if (value.IsImmediate()) {
|
||||||
@@ -490,7 +488,7 @@ private:
|
|||||||
case Type::U16: result = value.U16(); return true;
|
case Type::U16: result = value.U16(); return true;
|
||||||
case Type::U32: result = value.U32(); return true;
|
case Type::U32: result = value.U32(); return true;
|
||||||
case Type::U64: result = value.U64(); return true;
|
case Type::U64: result = value.U64(); return true;
|
||||||
case Type::F32: result = Float32Bits(value.F32Value()); return true;
|
case Type::F32: result = std::bit_cast<uint32_t>(value.F32Value()); return true;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -733,7 +731,7 @@ private:
|
|||||||
return false;
|
return false;
|
||||||
case ValueOpcode::ConvertF32U32:
|
case ValueOpcode::ConvertF32U32:
|
||||||
if (Arg(inst, 0, a)) {
|
if (Arg(inst, 0, a)) {
|
||||||
result = Float32Bits(static_cast<float>(static_cast<uint32_t>(a)));
|
result = std::bit_cast<uint32_t>(static_cast<float>(static_cast<uint32_t>(a)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -750,13 +748,13 @@ private:
|
|||||||
return false;
|
return false;
|
||||||
case ValueOpcode::FPMul32:
|
case ValueOpcode::FPMul32:
|
||||||
if (binary()) {
|
if (binary()) {
|
||||||
result = Float32Bits(Float32(a) * Float32(b));
|
result = std::bit_cast<uint32_t>(Float32(a) * Float32(b));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case ValueOpcode::FPTrunc32:
|
case ValueOpcode::FPTrunc32:
|
||||||
if (Arg(inst, 0, a)) {
|
if (Arg(inst, 0, a)) {
|
||||||
result = Float32Bits(std::trunc(Float32(a)));
|
result = std::bit_cast<uint32_t>(std::trunc(Float32(a)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -60,12 +60,12 @@ public:
|
|||||||
: parameters(parameters_) {
|
: parameters(parameters_) {
|
||||||
builder.AddMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
|
builder.AddMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
|
||||||
|
|
||||||
void_type = Type(spv::OpTypeVoid);
|
void_type = builder.Type(spv::OpTypeVoid);
|
||||||
uint_type = Type(spv::OpTypeInt, 32u, 0u);
|
uint_type = builder.Type(spv::OpTypeInt, 32u, 0u);
|
||||||
int_type = Type(spv::OpTypeInt, 32u, 1u);
|
int_type = builder.Type(spv::OpTypeInt, 32u, 1u);
|
||||||
float_type = Type(spv::OpTypeFloat, 32u);
|
float_type = builder.Type(spv::OpTypeFloat, 32u);
|
||||||
vec4_float_type = Type(spv::OpTypeVector, float_type, 4u);
|
vec4_float_type = builder.Type(spv::OpTypeVector, float_type, 4u);
|
||||||
function_type = Type(spv::OpTypeFunction, void_type);
|
function_type = builder.Type(spv::OpTypeFunction, void_type);
|
||||||
|
|
||||||
per_vertex_type = builder.DecoratedType(
|
per_vertex_type = builder.DecoratedType(
|
||||||
spv::OpTypeStruct,
|
spv::OpTypeStruct,
|
||||||
@@ -76,12 +76,12 @@ public:
|
|||||||
ptr_input_vec4_float = Pointer(spv::StorageClassInput, vec4_float_type);
|
ptr_input_vec4_float = Pointer(spv::StorageClassInput, vec4_float_type);
|
||||||
ptr_output_vec4_float = Pointer(spv::StorageClassOutput, vec4_float_type);
|
ptr_output_vec4_float = Pointer(spv::StorageClassOutput, vec4_float_type);
|
||||||
if (model == spv::ExecutionModelTessellationControl) {
|
if (model == spv::ExecutionModelTessellationControl) {
|
||||||
bool_type = Type(spv::OpTypeBool);
|
bool_type = builder.Type(spv::OpTypeBool);
|
||||||
vec2_bool_type = Type(spv::OpTypeVector, bool_type, 2u);
|
vec2_bool_type = builder.Type(spv::OpTypeVector, bool_type, 2u);
|
||||||
vec2_float_type = Type(spv::OpTypeVector, float_type, 2u);
|
vec2_float_type = builder.Type(spv::OpTypeVector, float_type, 2u);
|
||||||
ptr_output_float = Pointer(spv::StorageClassOutput, float_type);
|
ptr_output_float = Pointer(spv::StorageClassOutput, float_type);
|
||||||
} else {
|
} else {
|
||||||
vec3_float_type = Type(spv::OpTypeVector, float_type, 3u);
|
vec3_float_type = builder.Type(spv::OpTypeVector, float_type, 3u);
|
||||||
ptr_input_float = Pointer(spv::StorageClassInput, float_type);
|
ptr_input_float = Pointer(spv::StorageClassInput, float_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,8 +161,8 @@ public:
|
|||||||
Store(Access(ptr_output_vec4_float, outputs[i], invocation), value);
|
Store(Access(ptr_output_vec4_float, outputs[i], invocation), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Emit(spv::OpReturn);
|
builder.AddFunction(spv::OpReturn);
|
||||||
Emit(spv::OpFunctionEnd);
|
builder.AddFunction(spv::OpFunctionEnd);
|
||||||
return builder.Build();
|
return builder.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,27 +184,22 @@ public:
|
|||||||
Load(vec4_float_type, Access(ptr_input_vec4_float, inputs[i], index)));
|
Load(vec4_float_type, Access(ptr_input_vec4_float, inputs[i], index)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Emit(spv::OpReturn);
|
builder.AddFunction(spv::OpReturn);
|
||||||
Emit(spv::OpFunctionEnd);
|
builder.AddFunction(spv::OpFunctionEnd);
|
||||||
return builder.Build();
|
return builder.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename... Args>
|
|
||||||
uint32_t Type(spv::Op opcode, Args... operands) {
|
|
||||||
return builder.Type(opcode, operands...);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t Constant(uint32_t type, uint32_t value) {
|
uint32_t Constant(uint32_t type, uint32_t value) {
|
||||||
return builder.Constant(spv::OpConstant, type, value);
|
return builder.Constant(spv::OpConstant, type, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Pointer(spv::StorageClass storage, uint32_t type) {
|
uint32_t Pointer(spv::StorageClass storage, uint32_t type) {
|
||||||
return Type(spv::OpTypePointer, storage, type);
|
return builder.Type(spv::OpTypePointer, storage, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Array(uint32_t type, uint32_t size) {
|
uint32_t Array(uint32_t type, uint32_t size) {
|
||||||
return Type(spv::OpTypeArray, type, Uint(size));
|
return builder.Type(spv::OpTypeArray, type, Uint(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
@@ -221,11 +216,6 @@ private:
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
|
||||||
void Emit(spv::Op opcode, Args... operands) {
|
|
||||||
builder.AddFunction(opcode, operands...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
uint32_t Access(uint32_t pointer_type, uint32_t base, Args... indices) {
|
uint32_t Access(uint32_t pointer_type, uint32_t base, Args... indices) {
|
||||||
return Result(spv::OpAccessChain, pointer_type, base, indices...);
|
return Result(spv::OpAccessChain, pointer_type, base, indices...);
|
||||||
@@ -233,7 +223,7 @@ private:
|
|||||||
|
|
||||||
uint32_t Load(uint32_t type, uint32_t pointer) { return Result(spv::OpLoad, type, pointer); }
|
uint32_t Load(uint32_t type, uint32_t pointer) { return Result(spv::OpLoad, type, pointer); }
|
||||||
|
|
||||||
void Store(uint32_t pointer, uint32_t value) { Emit(spv::OpStore, pointer, value); }
|
void Store(uint32_t pointer, uint32_t value) { builder.AddFunction(spv::OpStore, pointer, value); }
|
||||||
|
|
||||||
uint32_t Int(uint32_t value) { return Constant(int_type, value); }
|
uint32_t Int(uint32_t value) { return Constant(int_type, value); }
|
||||||
|
|
||||||
|
|||||||
@@ -1005,8 +1005,4 @@ void ShaderDbgDumpInputInfo(const ShaderComputeInputInfo& info) {
|
|||||||
info.group_id[1] ? "true" : "false", info.group_id[2] ? "true" : "false");
|
info.group_id[1] ? "true" : "false", info.group_id[2] ? "true" : "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShaderAddressValid(uint64_t addr) {
|
|
||||||
return reinterpret_cast<const uint32_t*>(addr) != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Libs::Graphics
|
} // namespace Libs::Graphics
|
||||||
|
|||||||
@@ -303,7 +303,6 @@ void ShaderMapUserData(uint64_t addr, const ShaderMappedData& data);
|
|||||||
void ShaderDbgDumpInputInfo(const ShaderVertexInputInfo& info);
|
void ShaderDbgDumpInputInfo(const ShaderVertexInputInfo& info);
|
||||||
void ShaderDbgDumpInputInfo(const ShaderPixelInputInfo& info);
|
void ShaderDbgDumpInputInfo(const ShaderPixelInputInfo& info);
|
||||||
void ShaderDbgDumpInputInfo(const ShaderComputeInputInfo& info);
|
void ShaderDbgDumpInputInfo(const ShaderComputeInputInfo& info);
|
||||||
bool ShaderAddressValid(uint64_t addr);
|
|
||||||
|
|
||||||
} // namespace Libs::Graphics
|
} // namespace Libs::Graphics
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user