1#version 450 2/* Copyright (c) 2020 Themaister 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files (the 6 * "Software"), to deal in the Software without restriction, including 7 * without limitation the rights to use, copy, modify, merge, publish, 8 * distribute, sublicense, and/or sell copies of the Software, and to 9 * permit persons to whom the Software is furnished to do so, subject to 10 * the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 */ 23 24#include "small_types.h" 25 26layout(local_size_x_id = 3) in; 27 28layout(constant_id = 0) const int RDRAM_SIZE = 8 * 1024 * 1024; 29const int RDRAM_MASK_8 = RDRAM_SIZE - 1; 30const int RDRAM_MASK_16 = RDRAM_MASK_8 >> 1; 31const int RDRAM_MASK_32 = RDRAM_MASK_8 >> 2; 32layout(constant_id = 1) const int FB_SIZE_LOG2 = 0; 33layout(constant_id = 2) const bool COLOR_DEPTH_ALIAS = false; 34layout(constant_id = 4) const int NUM_SAMPLES = 1; 35 36layout(push_constant) uniform Registers 37{ 38 uint num_pixels, fb_addr, fb_depth_addr; 39} registers; 40 41layout(set = 0, binding = 0) readonly buffer RDRAMSingleSampled8 42{ 43 uint8_t elems[]; 44} vram8; 45 46layout(set = 0, binding = 0) readonly buffer RDRAMSingleSampled16 47{ 48 uint16_t elems[]; 49} vram16; 50 51layout(set = 0, binding = 0) readonly buffer RDRAMSingleSampled32 52{ 53 uint elems[]; 54} vram32; 55 56layout(set = 0, binding = 1) readonly buffer RDRAMHiddenSingleSampled 57{ 58 uint8_t elems[]; 59} hidden_vram; 60 61layout(set = 0, binding = 2) buffer RDRAMUpscalingReference8 62{ 63 uint8_t elems[]; 64} vram_reference8; 65 66layout(set = 0, binding = 2) buffer RDRAMUpscalingReference16 67{ 68 uint16_t elems[]; 69} vram_reference16; 70 71layout(set = 0, binding = 2) buffer RDRAMUpscalingReference32 72{ 73 uint elems[]; 74} vram_reference32; 75 76layout(set = 0, binding = 3) buffer RDRAMUpscaling8 77{ 78 uint8_t elems[]; 79} vram_upscaled8; 80 81layout(set = 0, binding = 3) buffer RDRAMUpscaling16 82{ 83 uint16_t elems[]; 84} vram_upscaled16; 85 86layout(set = 0, binding = 3) buffer RDRAMUpscaling32 87{ 88 uint elems[]; 89} vram_upscaled32; 90 91layout(set = 0, binding = 4) buffer RDRAMHiddenUpscaling 92{ 93 uint8_t elems[]; 94} hidden_vram_upscaled; 95 96void update_rdram_8(uint index) 97{ 98 index &= RDRAM_MASK_8; 99 100 uint real_word = uint(vram8.elems[index]); 101 uint reference_word = uint(vram_reference8.elems[index]); 102 103 if (real_word != reference_word) 104 { 105 uint real_hidden_word = uint(hidden_vram.elems[index >> 1u]); 106 for (int i = 0; i < NUM_SAMPLES; i++) 107 { 108 vram_upscaled8.elems[index + i * RDRAM_SIZE] = uint8_t(real_word); 109 if ((index & 1u) != 0u) 110 hidden_vram_upscaled.elems[(index >> 1u) + i * (RDRAM_SIZE >> 1)] = uint8_t(real_hidden_word); 111 } 112 vram_reference8.elems[index] = uint8_t(real_word); 113 } 114} 115 116void update_rdram_16(uint index) 117{ 118 index &= RDRAM_MASK_16; 119 120 uint real_word = uint(vram16.elems[index]); 121 uint reference_word = uint(vram_reference16.elems[index]); 122 123 if (real_word != reference_word) 124 { 125 uint real_hidden_word = uint(hidden_vram.elems[index]); 126 for (int i = 0; i < NUM_SAMPLES; i++) 127 { 128 vram_upscaled16.elems[index + i * (RDRAM_SIZE >> 1)] = uint16_t(real_word); 129 hidden_vram_upscaled.elems[index + i * (RDRAM_SIZE >> 1)] = uint8_t(real_hidden_word); 130 } 131 vram_reference16.elems[index] = uint16_t(real_word); 132 } 133} 134 135void update_rdram_32(uint index) 136{ 137 index &= RDRAM_MASK_32; 138 139 uint real_word = vram32.elems[index]; 140 uint reference_word = vram_reference32.elems[index]; 141 142 if (real_word != reference_word) 143 { 144 uint real_hidden_word0 = uint(hidden_vram.elems[2u * index]); 145 uint real_hidden_word1 = uint(hidden_vram.elems[2u * index + 1u]); 146 147 for (int i = 0; i < NUM_SAMPLES; i++) 148 { 149 vram_upscaled32.elems[index + i * (RDRAM_SIZE >> 2)] = real_word; 150 hidden_vram_upscaled.elems[2u * index + i * (RDRAM_SIZE >> 1)] = uint8_t(real_hidden_word0); 151 hidden_vram_upscaled.elems[2u * index + 1u + i * (RDRAM_SIZE >> 1)] = uint8_t(real_hidden_word1); 152 } 153 vram_reference32.elems[index] = real_word; 154 } 155} 156 157void main() 158{ 159 uint index = gl_GlobalInvocationID.x; 160 if (index >= registers.num_pixels) 161 return; 162 163 uint depth_index = index + registers.fb_depth_addr; 164 uint color_index = index + registers.fb_addr; 165 166 switch (FB_SIZE_LOG2) 167 { 168 case 0: 169 update_rdram_8(color_index); 170 break; 171 172 case 1: 173 update_rdram_16(color_index); 174 break; 175 176 case 2: 177 update_rdram_32(color_index); 178 break; 179 } 180 181 if (!COLOR_DEPTH_ALIAS) 182 update_rdram_16(depth_index); 183} 184