summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar namkazy2020-04-06 13:09:19 +0700
committerGravatar namkazy2020-04-06 13:09:19 +0700
commit2906372ba18b1c6238062c7ac91ccf9536fc649b (patch)
tree97dabf3cdb1f74a02ad6e725e6eceadccd8e943a /src
parentsilent warning (conversion error) (diff)
downloadyuzu-2906372ba18b1c6238062c7ac91ccf9536fc649b.tar.gz
yuzu-2906372ba18b1c6238062c7ac91ccf9536fc649b.tar.xz
yuzu-2906372ba18b1c6238062c7ac91ccf9536fc649b.zip
shader_decode: SULD.D implement bits64 and reverse shader ir init method to removed shader stage.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp6
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp2
-rw-r--r--src/video_core/shader/decode/image.cpp127
-rw-r--r--src/video_core/shader/shader_ir.cpp7
-rw-r--r--src/video_core/shader/shader_ir.h9
5 files changed, 105 insertions, 46 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index dc6825a00..046ee55a5 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -234,7 +234,7 @@ Shader CachedShader::CreateStageFromMemory(const ShaderParameters& params,
234 const std::size_t size_in_bytes = code.size() * sizeof(u64); 234 const std::size_t size_in_bytes = code.size() * sizeof(u64);
235 235
236 auto registry = std::make_shared<Registry>(shader_type, params.system.GPU().Maxwell3D()); 236 auto registry = std::make_shared<Registry>(shader_type, params.system.GPU().Maxwell3D());
237 const ShaderIR ir(code, shader_type, STAGE_MAIN_OFFSET, COMPILER_SETTINGS, *registry); 237 const ShaderIR ir(code, STAGE_MAIN_OFFSET, COMPILER_SETTINGS, *registry);
238 // TODO(Rodrigo): Handle VertexA shaders 238 // TODO(Rodrigo): Handle VertexA shaders
239 // std::optional<ShaderIR> ir_b; 239 // std::optional<ShaderIR> ir_b;
240 // if (!code_b.empty()) { 240 // if (!code_b.empty()) {
@@ -264,7 +264,7 @@ Shader CachedShader::CreateKernelFromMemory(const ShaderParameters& params, Prog
264 264
265 auto& engine = params.system.GPU().KeplerCompute(); 265 auto& engine = params.system.GPU().KeplerCompute();
266 auto registry = std::make_shared<Registry>(ShaderType::Compute, engine); 266 auto registry = std::make_shared<Registry>(ShaderType::Compute, engine);
267 const ShaderIR ir(code, ShaderType::Compute, KERNEL_MAIN_OFFSET, COMPILER_SETTINGS, *registry); 267 const ShaderIR ir(code, KERNEL_MAIN_OFFSET, COMPILER_SETTINGS, *registry);
268 const u64 uid = params.unique_identifier; 268 const u64 uid = params.unique_identifier;
269 auto program = BuildShader(params.device, ShaderType::Compute, uid, ir, *registry); 269 auto program = BuildShader(params.device, ShaderType::Compute, uid, ir, *registry);
270 270
@@ -341,7 +341,7 @@ void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading,
341 const bool is_compute = entry.type == ShaderType::Compute; 341 const bool is_compute = entry.type == ShaderType::Compute;
342 const u32 main_offset = is_compute ? KERNEL_MAIN_OFFSET : STAGE_MAIN_OFFSET; 342 const u32 main_offset = is_compute ? KERNEL_MAIN_OFFSET : STAGE_MAIN_OFFSET;
343 auto registry = MakeRegistry(entry); 343 auto registry = MakeRegistry(entry);
344 const ShaderIR ir(entry.code, entry.type, main_offset, COMPILER_SETTINGS, *registry); 344 const ShaderIR ir(entry.code, main_offset, COMPILER_SETTINGS, *registry);
345 345
346 std::shared_ptr<OGLProgram> program; 346 std::shared_ptr<OGLProgram> program;
347 if (precompiled_entry) { 347 if (precompiled_entry) {
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 7a8824ebc..557b9d662 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -162,7 +162,7 @@ CachedShader::CachedShader(Core::System& system, Tegra::Engines::ShaderType stag
162 ProgramCode program_code, u32 main_offset) 162 ProgramCode program_code, u32 main_offset)
163 : RasterizerCacheObject{host_ptr}, gpu_addr{gpu_addr}, cpu_addr{cpu_addr}, 163 : RasterizerCacheObject{host_ptr}, gpu_addr{gpu_addr}, cpu_addr{cpu_addr},
164 program_code{std::move(program_code)}, registry{stage, GetEngine(system, stage)}, 164 program_code{std::move(program_code)}, registry{stage, GetEngine(system, stage)},
165 shader_ir{this->program_code, stage, main_offset, compiler_settings, registry}, 165 shader_ir{this->program_code, main_offset, compiler_settings, registry},
166 entries{GenerateShaderEntries(shader_ir)} {} 166 entries{GenerateShaderEntries(shader_ir)} {}
167 167
168CachedShader::~CachedShader() = default; 168CachedShader::~CachedShader() = default;
diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp
index 8d4530386..68913085f 100644
--- a/src/video_core/shader/decode/image.cpp
+++ b/src/video_core/shader/decode/image.cpp
@@ -271,6 +271,40 @@ std::size_t GetImageTypeNumCoordinates(Tegra::Shader::ImageType image_type) {
271} 271}
272} // Anonymous namespace 272} // Anonymous namespace
273 273
274Node ShaderIR::GetComponentValue(ComponentType component_type, u32 component_size,
275 const Node original_value, bool* is_signed) {
276 switch (component_type) {
277 case ComponentType::SNORM: {
278 *is_signed = true;
279 // range [-1.0, 1.0]
280 auto cnv_value = Operation(OperationCode::FMul, original_value,
281 Immediate((1 << component_size) / 2.f - 1.f));
282 cnv_value = SignedOperation(OperationCode::ICastFloat, is_signed, std::move(cnv_value));
283 return BitfieldExtract(std::move(cnv_value), 0, component_size);
284 }
285 case ComponentType::SINT:
286 case ComponentType::UNORM: {
287 *is_signed = component_type == ComponentType::SINT;
288 // range [0.0, 1.0]
289 auto cnv_value =
290 Operation(OperationCode::FMul, original_value, Immediate((1 << component_size) - 1.f));
291 return SignedOperation(OperationCode::ICastFloat, is_signed, std::move(cnv_value));
292 }
293 case ComponentType::UINT: // range [0, (1 << component_size) - 1]
294 *is_signed = false;
295 return original_value;
296 case ComponentType::FLOAT:
297 if (component_size == 16) {
298 return Operation(OperationCode::HCastFloat, original_value);
299 } else {
300 return original_value;
301 }
302 default:
303 UNIMPLEMENTED_MSG("Unimplement component type={}", component_type);
304 return original_value;
305 }
306}
307
274u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { 308u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) {
275 const Instruction instr = {program_code[pc]}; 309 const Instruction instr = {program_code[pc]};
276 const auto opcode = OpCode::Decode(instr); 310 const auto opcode = OpCode::Decode(instr);
@@ -309,7 +343,8 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) {
309 SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i)); 343 SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i));
310 } 344 }
311 } else if (instr.suldst.mode == Tegra::Shader::SurfaceDataMode::D_BA) { 345 } else if (instr.suldst.mode == Tegra::Shader::SurfaceDataMode::D_BA) {
312 UNIMPLEMENTED_IF(instr.suldst.GetStoreDataLayout() != StoreType::Bits32); 346 UNIMPLEMENTED_IF(instr.suldst.GetStoreDataLayout() != StoreType::Bits32 &&
347 instr.suldst.GetStoreDataLayout() != StoreType::Bits64);
313 348
314 auto descriptor = [this, instr] { 349 auto descriptor = [this, instr] {
315 std::optional<Tegra::Engines::SamplerDescriptor> descriptor; 350 std::optional<Tegra::Engines::SamplerDescriptor> descriptor;
@@ -333,7 +368,6 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) {
333 switch (instr.suldst.GetStoreDataLayout()) { 368 switch (instr.suldst.GetStoreDataLayout()) {
334 case StoreType::Bits32: { 369 case StoreType::Bits32: {
335 u32 shifted_counter = 0; 370 u32 shifted_counter = 0;
336 // value should be RGBA format
337 Node value = Immediate(0); 371 Node value = Immediate(0);
338 for (u32 element = 0; element < 4; ++element) { 372 for (u32 element = 0; element < 4; ++element) {
339 if (!IsComponentEnabled(comp_mask, element)) { 373 if (!IsComponentEnabled(comp_mask, element)) {
@@ -343,39 +377,12 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) {
343 const auto component_size = GetComponentSize(descriptor.format, element); 377 const auto component_size = GetComponentSize(descriptor.format, element);
344 bool is_signed = true; 378 bool is_signed = true;
345 MetaImage meta{image, {}, element}; 379 MetaImage meta{image, {}, element};
346 const Node original_value = 380
347 Operation(OperationCode::ImageLoad, meta, GetCoordinates(type)); 381 Node converted_value = GetComponentValue(
348 382 component_type, component_size,
349 Node converted_value = [&] { 383 Operation(OperationCode::ImageLoad, meta, GetCoordinates(type)),
350 switch (component_type) { 384 &is_signed);
351 case ComponentType::SNORM: { 385
352 is_signed = true;
353 // range [-1.0, 1.0]
354 auto cnv_value =
355 Operation(OperationCode::FMul, original_value, Immediate(127.f));
356 cnv_value = SignedOperation(OperationCode::ICastFloat, is_signed,
357 std::move(cnv_value));
358 return BitfieldExtract(std::move(cnv_value), 0, 8);
359 }
360 case ComponentType::SINT:
361 case ComponentType::UNORM: {
362 is_signed = false;
363 // range [0.0, 1.0]
364 auto cnv_value =
365 Operation(OperationCode::FMul, original_value, Immediate(255.f));
366 return SignedOperation(OperationCode::ICastFloat, is_signed,
367 std::move(cnv_value));
368 }
369 case ComponentType::UINT: // range [0, 255]
370 is_signed = false;
371 return original_value;
372 case ComponentType::FLOAT:
373 return original_value;
374 default:
375 UNIMPLEMENTED_MSG("Unimplement component type={}", component_type);
376 return original_value;
377 }
378 }();
379 // shift element to correct position 386 // shift element to correct position
380 const auto shifted = shifted_counter; 387 const auto shifted = shifted_counter;
381 if (shifted > 0) { 388 if (shifted > 0) {
@@ -391,6 +398,56 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) {
391 SetRegister(bb, instr.gpr0.Value(), std::move(value)); 398 SetRegister(bb, instr.gpr0.Value(), std::move(value));
392 break; 399 break;
393 } 400 }
401 case StoreType::Bits64: {
402 u32 indexer = 0;
403 u32 shifted_counter = 0;
404 Node value = Immediate(0);
405 for (u32 element = 0; element < 4; ++element) {
406 if (!IsComponentEnabled(comp_mask, element)) {
407 continue;
408 }
409 const auto component_type = GetComponentType(descriptor, element);
410 const auto component_size = GetComponentSize(descriptor.format, element);
411
412 bool is_signed = true;
413 MetaImage meta{image, {}, element};
414
415 Node converted_value = GetComponentValue(
416 component_type, component_size,
417 Operation(OperationCode::ImageLoad, meta, GetCoordinates(type)),
418 &is_signed);
419
420 // shift element to correct position
421 const auto shifted = shifted_counter;
422 if (shifted > 0) {
423 converted_value =
424 SignedOperation(OperationCode::ILogicalShiftLeft, is_signed,
425 std::move(converted_value), Immediate(shifted));
426 }
427 shifted_counter += component_size;
428
429 // add value into result
430 value = Operation(OperationCode::UBitwiseOr, value, std::move(converted_value));
431
432 // if we shifted enough for 1 byte -> we save it into temp
433 if (shifted_counter >= 32) {
434 SetTemporary(bb, indexer++, std::move(value));
435
436 // we only use 2 bytes for bits64
437 if (indexer >= 2) {
438 break;
439 }
440
441 // reset counter and value to prepare pack next byte
442 value = Immediate(0);
443 shifted_counter = 0;
444 }
445 }
446 for (u32 i = 0; i < indexer; ++i) {
447 SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i));
448 }
449 break;
450 }
394 default: 451 default:
395 UNREACHABLE(); 452 UNREACHABLE();
396 break; 453 break;
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index bbd86a2c5..baf7188d2 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -24,10 +24,9 @@ using Tegra::Shader::PredCondition;
24using Tegra::Shader::PredOperation; 24using Tegra::Shader::PredOperation;
25using Tegra::Shader::Register; 25using Tegra::Shader::Register;
26 26
27ShaderIR::ShaderIR(const ProgramCode& program_code, Tegra::Engines::ShaderType shader_stage, 27ShaderIR::ShaderIR(const ProgramCode& program_code, u32 main_offset, CompilerSettings settings,
28 u32 main_offset, CompilerSettings settings, Registry& registry) 28 Registry& registry)
29 : program_code{program_code}, shader_stage{shader_stage}, 29 : program_code{program_code}, main_offset{main_offset}, settings{settings}, registry{registry} {
30 main_offset{main_offset}, settings{settings}, registry{registry} {
31 Decode(); 30 Decode();
32 PostDecode(); 31 PostDecode();
33} 32}
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index e531181cd..408cce71e 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -68,8 +68,8 @@ struct GlobalMemoryUsage {
68 68
69class ShaderIR final { 69class ShaderIR final {
70public: 70public:
71 explicit ShaderIR(const ProgramCode& program_code, Tegra::Engines::ShaderType shader_stage, 71 explicit ShaderIR(const ProgramCode& program_code, u32 main_offset, CompilerSettings settings,
72 u32 main_offset, CompilerSettings settings, Registry& registry); 72 Registry& registry);
73 ~ShaderIR(); 73 ~ShaderIR();
74 74
75 const std::map<u32, NodeBlock>& GetBasicBlocks() const { 75 const std::map<u32, NodeBlock>& GetBasicBlocks() const {
@@ -312,6 +312,10 @@ private:
312 /// Conditionally saturates a half float pair 312 /// Conditionally saturates a half float pair
313 Node GetSaturatedHalfFloat(Node value, bool saturate = true); 313 Node GetSaturatedHalfFloat(Node value, bool saturate = true);
314 314
315 /// Get image component value by type and size
316 Node GetComponentValue(Tegra::Texture::ComponentType component_type, u32 component_size,
317 const Node original_value, bool* is_signed);
318
315 /// Returns a predicate comparing two floats 319 /// Returns a predicate comparing two floats
316 Node GetPredicateComparisonFloat(Tegra::Shader::PredCondition condition, Node op_a, Node op_b); 320 Node GetPredicateComparisonFloat(Tegra::Shader::PredCondition condition, Node op_a, Node op_b);
317 /// Returns a predicate comparing two integers 321 /// Returns a predicate comparing two integers
@@ -419,7 +423,6 @@ private:
419 u32 NewCustomVariable(); 423 u32 NewCustomVariable();
420 424
421 const ProgramCode& program_code; 425 const ProgramCode& program_code;
422 const Tegra::Engines::ShaderType shader_stage;
423 const u32 main_offset; 426 const u32 main_offset;
424 const CompilerSettings settings; 427 const CompilerSettings settings;
425 Registry& registry; 428 Registry& registry;