Changeset 163:1aae525e1e79
- Timestamp:
- 03/21/2012 03:26:46 PM (15 months ago)
- Author:
- Andreas Schaefer <gentryx@…>
- Branch:
- default
- Message:
-
camera frames are now propated to the GPU code
- Location:
- src/examples/flowingcanvas
- Files:
-
Legend:
- Unmodified
- Added
- Removed
-
|
r162
|
r163
|
|
| 21 | 21 | { |
| 22 | 22 | public: |
| | 23 | __host__ __device__ |
| 23 | 24 | Particle(const float& pos0 = 0, const float& pos1 = 0, const float& _lifetime = 1000) : |
| 24 | 25 | lifetime(_lifetime) |
| … |
… |
|
| 30 | 31 | } |
| 31 | 32 | |
| | 33 | __host__ __device__ |
| 32 | 34 | void update(const float& deltaT, const float& force0, const float& force1, const float& forceFactor, const float& friction) |
| 33 | 35 | { |
| … |
… |
|
| 163 | 165 | } |
| 164 | 166 | |
| 165 | | void readCam(unsigned char *frame, const float& factorX, const float& factorY, const int& width, const int& height) |
| 166 | | { |
| 167 | | int posX = pos[0] * factorX; |
| 168 | | int posY = pos[1] * factorY; |
| 169 | | |
| 170 | | int index = posY * width * 3 + posX * 3; |
| 171 | | cameraPixel = (0xff << 24) + |
| 172 | | (frame[index + 0] << 16) + |
| 173 | | (frame[index + 1] << 8) + |
| 174 | | (frame[index + 2] << 0); |
| 175 | | |
| 176 | | int val = (int)frame[index + 0] + (int)frame[index + 1] + (int)frame[index + 2]; |
| | 167 | |
| | 168 | __host__ __device__ |
| | 169 | void readCam(const unsigned char& r, const unsigned char& g, const unsigned char& b) |
| | 170 | { |
| | 171 | cameraPixel = (0xff << 24) + (r << 16) + (g << 8) + (b << 0); |
| | 172 | |
| | 173 | int val = (int)r + (int)g + (int)b; |
| 177 | 174 | if (val < 500) { |
| 178 | 175 | cameraLevel = 1.0; |
| 179 | 176 | } else { |
| 180 | | cameraLevel = std::max(0.0, cameraLevel - 0.05); |
| 181 | | } |
| | 177 | cameraLevel = max(0.0, cameraLevel - 0.05); |
| | 178 | } |
| | 179 | } |
| | 180 | |
| | 181 | __host__ __device__ |
| | 182 | float max(const float& a, const float& b) |
| | 183 | { |
| | 184 | return a > b ? a : b; |
| 182 | 185 | } |
| 183 | 186 | |
-
|
r159
|
r163
|
|
| 33 | 33 | for (int x = 0; x < dim.x(); ++x) { |
| 34 | 34 | Coord<2> c(x, y); |
| 35 | | (*this->curGrid)[c].readCam(&cameraFrame[0], factorX, factorY, cameraFrameWidth, cameraFrameHeight); |
| | 35 | int index = (int)(y * factorY) * cameraFrameWidth + x * factorX; |
| | 36 | unsigned char *pixel = &cameraFrame[3 * index]; |
| | 37 | (*this->curGrid)[c].readCam(pixel[0], pixel[1], pixel[2]); |
| 36 | 38 | } |
| 37 | 39 | } |
-
|
r162
|
r163
|
|
| 5 | 5 | #include <libgeodecomp/misc/grid.h> |
| 6 | 6 | |
| | 7 | // fixme: kernels need to be templates. should be included by GPUSimulator |
| 7 | 8 | __global__ void updateKernel(CanvasCell *curGrid, CanvasCell *newGrid, unsigned width, unsigned nanoStep) |
| 8 | 9 | { |
| … |
… |
|
| 38 | 39 | } |
| 39 | 40 | |
| | 41 | |
| | 42 | __global__ void updateCam(CanvasCell *grid, unsigned char *cameraBuffer, float factorX, float factorY, unsigned widthGrid, unsigned widthBuffer) |
| | 43 | { |
| | 44 | int x = blockDim.x * blockIdx.x + threadIdx.x; |
| | 45 | int y = blockDim.y * blockIdx.y + threadIdx.y; |
| | 46 | int indexGrid = (y + 1) * widthGrid + x + 1; |
| | 47 | int indexBuffer = (int)(y * factorY) * widthBuffer + x * factorX; |
| | 48 | unsigned char *pixel = cameraBuffer + indexBuffer * 3; |
| | 49 | |
| | 50 | grid[indexGrid].readCam(pixel[0], pixel[1], pixel[2]); |
| | 51 | } |
| | 52 | |
| 40 | 53 | namespace LibGeoDecomp { |
| 41 | 54 | |
| 42 | 55 | // fixme: this is hardcoded to 2d ATM |
| | 56 | // fixme: move to dedicated file |
| 43 | 57 | template<typename CELL_TYPE> |
| 44 | 58 | class GPUSimulator : public MonolithicSimulator<CELL_TYPE> |
| … |
… |
|
| 50 | 64 | |
| 51 | 65 | GPUSimulator(Initializer<CELL_TYPE> *initializer, const int& device = 0) : |
| 52 | | MonolithicSimulator<CELL_TYPE>(initializer) |
| | 66 | MonolithicSimulator<CELL_TYPE>(initializer), |
| | 67 | inputBufferDevice(0), |
| | 68 | inputBufferSize(0) |
| 53 | 69 | { |
| 54 | 70 | Coord<DIM> dim = this->initializer->gridDimensions(); |
| … |
… |
|
| 58 | 74 | cudaSetDevice(device); |
| 59 | 75 | int byteSize = dim.prod() * sizeof(CELL_TYPE); |
| 60 | | cudaMalloc(&transferGrid, byteSize); |
| 61 | | cudaMemcpy(transferGrid, gridHost.baseAddress(), byteSize, cudaMemcpyHostToDevice); |
| | 76 | cudaMalloc(&transferGridDevice, byteSize); |
| | 77 | cudaMemcpy(transferGridDevice, gridHost.baseAddress(), byteSize, cudaMemcpyHostToDevice); |
| 62 | 78 | |
| 63 | 79 | // pad actual grids to avoid edge cell handling |
| … |
… |
|
| 73 | 89 | dim3 gridDim; |
| 74 | 90 | genKernelDimensions(&blockDim, &gridDim); |
| 75 | | loadGridFromTransferBuffer<<<gridDim, blockDim>>>(curGridDevice, transferGrid, gridWidth() + 2, gridWidth()); |
| | 91 | loadGridFromTransferBuffer<<<gridDim, blockDim>>>(curGridDevice, transferGridDevice, gridWidth() + 2, gridWidth()); |
| | 92 | |
| | 93 | allocInputBuffer(Coord<2>(1, 1)); |
| 76 | 94 | checkCudaError(); |
| 77 | 95 | } |
| … |
… |
|
| 79 | 97 | virtual ~GPUSimulator() |
| 80 | 98 | { |
| 81 | | cudaFree(&curGridDevice); |
| 82 | | cudaFree(&newGridDevice); |
| | 99 | cudaFree(transferGridDevice); |
| | 100 | cudaFree(curGridDevice); |
| | 101 | cudaFree(newGridDevice); |
| | 102 | cudaFree(inputBufferDevice); |
| 83 | 103 | } |
| 84 | 104 | |
| … |
… |
|
| 104 | 124 | dim3 gridDim; |
| 105 | 125 | genKernelDimensions(&blockDim, &gridDim); |
| 106 | | storeGridToTransferBuffer<<<gridDim, blockDim>>>(curGridDevice, transferGrid, gridWidth() + 2, gridWidth()); |
| | 126 | storeGridToTransferBuffer<<<gridDim, blockDim>>>(curGridDevice, transferGridDevice, gridWidth() + 2, gridWidth()); |
| 107 | 127 | int byteSize = gridHost.getDimensions().prod() * sizeof(CELL_TYPE); |
| 108 | | cudaMemcpy(gridHost.baseAddress(), transferGrid, byteSize, cudaMemcpyDeviceToHost); |
| | 128 | cudaMemcpy(gridHost.baseAddress(), transferGridDevice, byteSize, cudaMemcpyDeviceToHost); |
| 109 | 129 | checkCudaError(); |
| 110 | 130 | return &gridHost; |
| | 131 | } |
| | 132 | |
| | 133 | virtual void updateInputBuffer(unsigned char *data, const Coord<DIM>& inputDim) |
| | 134 | { |
| | 135 | allocInputBuffer(inputDim); |
| | 136 | // fixme: set element size externally |
| | 137 | int byteSize = inputDim.prod() * 3 * sizeof(unsigned char); |
| | 138 | cudaMemcpy(inputBufferDevice, data, byteSize, cudaMemcpyHostToDevice); |
| | 139 | |
| | 140 | Coord<2> simGridDim = this->getInitializer()->gridDimensions(); |
| | 141 | float factorX = 1.0 * inputDim.x() / simGridDim.x(); |
| | 142 | float factorY = 1.0 * inputDim.y() / simGridDim.y(); |
| | 143 | |
| | 144 | dim3 blockDim; |
| | 145 | dim3 gridDim; |
| | 146 | genKernelDimensions(&blockDim, &gridDim); |
| | 147 | updateCam<<<gridDim, blockDim>>>(curGridDevice, inputBufferDevice, factorX, factorY, gridWidth() + 2, inputDim.x()); |
| 111 | 148 | } |
| 112 | 149 | |
| 113 | 150 | private: |
| 114 | 151 | GridType gridHost; |
| 115 | | CELL_TYPE *transferGrid; |
| | 152 | CELL_TYPE *transferGridDevice; |
| 116 | 153 | CELL_TYPE *curGridDevice; |
| 117 | 154 | CELL_TYPE *newGridDevice; |
| 118 | | |
| | 155 | unsigned char *inputBufferDevice; |
| | 156 | int inputBufferSize; |
| | 157 | |
| | 158 | void allocInputBuffer(const Coord<DIM>& dim) |
| | 159 | { |
| | 160 | // fixme: set element size externally |
| | 161 | int byteSize = dim.prod() * 3 * sizeof(unsigned char); |
| | 162 | if (byteSize == inputBufferSize) { |
| | 163 | return; |
| | 164 | } |
| | 165 | |
| | 166 | if (inputBufferDevice != 0) { |
| | 167 | cudaFree(inputBufferDevice); |
| | 168 | } |
| | 169 | |
| | 170 | cudaMalloc(&inputBufferDevice, byteSize); |
| | 171 | checkCudaError(); |
| | 172 | } |
| | 173 | |
| 119 | 174 | void checkCudaError() |
| 120 | 175 | { |
| … |
… |
|
| 159 | 214 | typedef Grid<CELL_TYPE, Topology> GridType; |
| 160 | 215 | typedef std::vector<boost::shared_ptr<Writer<CELL_TYPE> > > WriterVector; |
| | 216 | static const int DIM = Topology::DIMENSIONS; |
| 161 | 217 | |
| 162 | 218 | InteractiveSimulatorGPU(QObject *parent, Initializer<CELL_TYPE> *initializer) : |
| … |
… |
|
| 170 | 226 | virtual void readCam() |
| 171 | 227 | { |
| 172 | | std::cout << "fixme InteractiveSimulatorGPU::readCam()\n"; |
| | 228 | Coord<DIM> dim = this->initializer->gridDimensions(); |
| | 229 | this->updateInputBuffer(&cameraFrame[0], Coord<2>(cameraFrameWidth, cameraFrameHeight)); |
| 173 | 230 | } |
| 174 | 231 | |
| … |
… |
|
| 182 | 239 | virtual void update() |
| 183 | 240 | { |
| 184 | | // for (int fixme = 0; fixme < 500; ++fixme) |
| 185 | | GPUSimulator<CELL_TYPE>::step(); |
| 186 | | // sleep(1); |
| | 241 | for (int fixme = 0; fixme < 500; ++fixme) |
| | 242 | GPUSimulator<CELL_TYPE>::step(); |
| | 243 | sleep(1); |
| 187 | 244 | } |
| 188 | 245 | |
-
|
r162
|
r163
|
|
| 27 | 27 | flow.resize(1200, 900); |
| 28 | 28 | |
| 29 | | // InteractiveSimulatorGPU<CanvasCell> *sim = new InteractiveSimulatorGPU<CanvasCell>( |
| 30 | | InteractiveSimulatorCPU<CanvasCell> *sim = new InteractiveSimulatorCPU<CanvasCell>( |
| | 29 | InteractiveSimulatorGPU<CanvasCell> *sim = new InteractiveSimulatorGPU<CanvasCell>( |
| | 30 | // InteractiveSimulatorCPU<CanvasCell> *sim = new InteractiveSimulatorCPU<CanvasCell>( |
| 31 | 31 | &flow, |
| 32 | 32 | new CanvasInitializer()); |