#pragma once
#include <d3d11.h>
#include <memory>

#include "core/renderer/renderer_texture.h"

// DX11纹理
class dx_texture : public renderer_texture {
public:
    dx_texture(const Eigen::Vector2i& size, texture_format format, device_memory_type in_memory_type, uint32_t count = 1);
    ~dx_texture() override;

    void* lock(uint32_t* out_row_pitch) override;
    void unlock() override;

    void* lock(uint32_t index, uint32_t* out_row_pitch);
    void unlock(uint32_t index) const;

    void update_subresource(const Eigen::AlignedBox2i& in_area, const void* in_buffer, uint32_t in_row_pitch) override;
    void update_subresource(uint32_t index, const Eigen::AlignedBox2i& in_area, const void* in_buffer, uint32_t in_row_pitch);

    bool resize(const Eigen::Vector2i& size) override;
    Eigen::Vector2i size() override;

    [[nodiscard]] ID3D11ShaderResourceView* get_srv() const { return srv; }
    void* get_native_handle() override { return m_texture; }
    void* get_shader_resource_view() override { return srv; }

    [[nodiscard]] uint32_t get_count() const;
    void set_count(uint32_t in_count);
private:
    bool create_texture(const Eigen::Vector2i& in_size, texture_format in_format, device_memory_type in_memory_type, uint32_t in_count = 1);
    void release_texture();

    ID3D11Texture2D* m_texture{};
    ID3D11ShaderResourceView* srv{};
    device_memory_type memory_type;

    D3D11_TEXTURE2D_DESC upload_desc;
    ID3D11Texture2D* upload_texture{};
};
