1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsCorePrerequisites.h"
6
7namespace bs
8{
9 /** @addtogroup Implementation
10 * @{
11 */
12
13 /**
14 * You can use this class as a storage for reading and writing from/to various GPU resources. It is meant to be created
15 * on sim thread and used on the core thread. This class is abstract and specific resource types need to implement their
16 * own type of GpuResourceData.
17 *
18 * @note
19 * Normal use of this class involves requesting an instance of GpuResourceData from a Resource, then scheduling a read
20 * or write on that resource using the provided instance. Instance will be locked while it is used by the core thread
21 * and sim thread will be allowed to access it when the operation ends. Caller can track AsyncOp%s regarding the
22 * read/write operation to be notified when it is complete.
23 * @note
24 * If you allocate an internal buffer to store the resource data, the ownership of the buffer will always remain with
25 * the initial instance of the class. If that initial instance is deleted, any potential copies will point to garbage
26 * data.
27 */
28 class BS_CORE_EXPORT GpuResourceData : public IReflectable
29 {
30 public:
31 GpuResourceData() = default;
32 GpuResourceData(const GpuResourceData& copy);
33 virtual ~GpuResourceData();
34
35 GpuResourceData& operator=(const GpuResourceData& rhs);
36
37 /** Returns pointer to the internal buffer. */
38 UINT8* getData() const;
39
40 /**
41 * Allocates an internal buffer of a certain size. If there is another buffer already allocated, it will be freed
42 * and new one will be allocated. Buffer size is determined based on parameters used for initializing the class.
43 */
44 void allocateInternalBuffer();
45
46 /**
47 * Allocates an internal buffer of a certain size. If there is another buffer already allocated, it will be freed
48 * and new one will be allocated.
49 *
50 * @param[in] size The size of the buffer in bytes.
51 */
52 void allocateInternalBuffer(UINT32 size);
53
54 /**
55 * Frees the internal buffer that was allocated using allocateInternalBuffer(). Called automatically when the
56 * instance of the class is destroyed.
57 */
58 void freeInternalBuffer();
59
60 /**
61 * Makes the internal data pointer point to some external data. No copying is done, so you must ensure that external
62 * data exists as long as this class uses it. You are also responsible for deleting the data when you are done
63 * with it.
64 *
65 * @note If any internal data is allocated, it is freed.
66 */
67 void setExternalBuffer(UINT8* data);
68
69 /** Checks if the internal buffer is locked due to some other thread using it. */
70 bool isLocked() const { return mLocked; }
71
72 /** Locks the data and makes it available only to the core thread. */
73 void _lock() const;
74
75 /** Unlocks the data and makes it available to all threads. */
76 void _unlock() const;
77
78 protected:
79 /**
80 * Returns the size of the internal buffer in bytes. This is calculated based on parameters provided upon
81 * construction and specific implementation details.
82 */
83 virtual UINT32 getInternalBufferSize() const = 0;
84
85 private:
86 UINT8* mData = nullptr;
87 bool mOwnsData = false;
88 mutable bool mLocked = false;
89
90 /************************************************************************/
91 /* SERIALIZATION */
92 /************************************************************************/
93 public:
94 friend class GpuResourceDataRTTI;
95 static RTTITypeBase* getRTTIStatic();
96 RTTITypeBase* getRTTI() const override;
97 };
98
99 /** @} */
100}